Skip to documentation

Generic examplesSign in to personalize workspace URLs.

Download OpenAPI

API reference

Generated schemas and tested server-side examples. Eligibility badges describe the current plan contract; scopes, creator permissions, quotas and evidence availability are checked separately.

Display filter only. Compare plans and limits
57 documented operations

The interactive schema reference loads in your browser. Endpoint summaries are available above.

Error recovery and API guidance

API reference

Details are generated from the bound catalogue, including schemas, scopes, actions, eligible plans, units and bounds. Bounded list lengths/windows are not unbounded pagination promises; do not invent a cursor when the response has none.

Error recovery

The closed body contains error.code, message, requestId and optional bounded details. Retain request IDs, never Authorization or raw provider exceptions.

Status/codeRecovery
400 invalid_requestCorrect required fields, parent IDs, units, date order and semantic constraints.
401 unauthenticatedCheck secret, workspace binding, expiry, revocation and rotation grace.
403 forbiddenCheck key scope, current creator role/action and data access. Scope cannot override role denial.
403 quota_exceededInspect limit/usage and actual plan/window; reduce range or wait for the appropriate reset.
404 not_foundRecheck current slugs and directory IDs. Inactive/foreign/inaccessible targets deliberately share this refusal.
409 conflictRead latest version and decide on a new edit/key.
409 idempotency_conflictRecover the original method/path/payload; use a new key only for a genuinely new intent.
409 operation_in_progressReconcile the original external attempt; do not blindly repeat it.
429 rate_limitedHonor Retry-After, reduce concurrency and respect UTC minute buckets.
503 temporarily_unavailableKeep request ID/attempt identity; check existing saved outputs before retrying writes.
500 internal_errorKeep request ID; check persistence before retrying. Do not include secrets in support material.

Reads are private/no-store. Uploads use the specified raw-byte MIME type and PDF returns bytes. Zero is measured only when coverage establishes available evidence.

Intelligence and administrative reads

Read delivery intelligence

Operation: commandCenter.read · GET /command-center

Read the five delivery KPI families and the selected project's readiness and evidence sources for automation or an external dashboard. Optional clientId and projectId select an accessible dataset; when both are present they must refer to the same client. The response retains the app's selection and calculations. Start/end/tz travel together; omitted dates use the effective plan's reporting window. This is a single response with no pagination. Preserve null, unavailable and partial evidence, source provenance, confidence qualifiers and currency units; absent evidence is not zero. Dates are civil dates in the supplied IANA zone. No individual performance ranking is returned. Requires a current workspace member, this operation's exact key scope and current creator permission. Invalid filters return 400; missing or foreign resources return 404; missing permission or an effective plan restriction returns 403. Revoked or expired keys return 401; throttled requests return 429 with Retry-After.

Required key scope: command-center:read. Current creator action: command_center.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.

  • start, end and tz travel together; start must not follow end.

  • tz must be a recognized IANA time zone; explicit historical dates remain subject to the current effective reporting window.

  • When clientId and projectId are both supplied, the project must belong to that client.

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

View schema or synthetic response
JSON

[
  {
    "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" } }, { "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": "start", "required": false, "schema": { "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" } }, { "in": "query", "name": "end", "required": false, "schema": { "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" } }, { "in": "query", "name": "tz", "required": false, "schema": { "maxLength": 64, "minLength": 1, "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

{
  "activeClientQuestion": {
    "canEdit": false,
    "question": null
  },
  "costEstimate": {
    "launchDecision": null,
    "source": null,
    "status": "not_set"
  },
  "directory": {
    "clients": [
      {
        "id": "00000000-0000-4000-8000-000000000005",
        "name": "Hidden by selection"
      },
      {
        "id": "33333333-3333-4333-8333-333333333333",
        "name": "Synthetic visible client"
      }
    ],
    "projects": [
      {
        "clientId": "00000000-0000-4000-8000-000000000005",
        "id": "00000000-0000-4000-8000-000000000006",
        "name": "Hidden by selection",
        "status": "active"
      },
      {
        "clientId": "33333333-3333-4333-8333-333333333333",
        "id": "11111111-1111-4111-8111-111111111111",
        "name": "Synthetic visible project",
        "status": "active"
      }
    ],
    "selectedClientId": "00000000-0000-4000-8000-000000000005",
    "selectedProjectId": "00000000-0000-4000-8000-000000000006"
  },
  "engagementBaseline": {
    "contractedAmount": false,
    "scopeLockDate": false
  },
  "flow": {
    "inputs": [
      {
        "color": "blue",
        "count": 0,
        "id": "tracker",
        "label": "Tracker items",
        "noun": "issues",
        "state": "not_connected"
      },
      {
        "color": "blue",
        "count": 0,
        "id": "code",
        "label": "Code changes",
        "noun": "changes",
        "state": "not_connected"
      },
      {
        "color": "purple",
        "count": 0,
        "id": "calendar",
        "label": "Calendar",
        "noun": "meetings",
        "state": "not_connected"
      },
      {
        "color": "purple",
        "count": 0,
        "id": "ai",
        "label": "AI-assisted",
        "noun": "assisted changes",
        "state": "not_connected"
      },
      {
        "color": "teal",
        "count": 0,
        "id": "release",
        "label": "Releases",
        "noun": "releases",
        "state": "not_connected"
      }
    ],
    "output": null
  },
  "insights": [
    {
      "body": "Report coverage is limited by **contracts** — not connected",
      "id": "coverage:commercial",
      "kind": "warn",
      "meta": "0 of 5 sources reporting"
    },
    {
      "body": "Report coverage is limited by **tracker** — not connected",
      "id": "coverage:tracker",
      "kind": "warn",
      "meta": "0 of 5 sources reporting"
    },
    {
      "body": "Report coverage is limited by **code** — not connected",
      "id": "coverage:code",
      "kind": "warn",
      "meta": "0 of 5 sources reporting"
    },
    {
      "body": "Report coverage is limited by **releases** — not connected",
      "id": "coverage:release",
      "kind": "warn",
      "meta": "0 of 5 sources reporting"
    },
    {
      "body": "Report coverage is limited by **calendar** — not connected",
      "id": "coverage:calendar",
      "kind": "warn",
      "meta": "0 of 5 sources reporting"
    }
  ],
  "kpis": [
    {
      "availability": "unavailable",
      "context": "Add a contracted amount to an engagement to calculate delivery investment.",
      "evidenceCount": 0,
      "evidencePath": "/workspaces/22222222-2222-4222-8222-222222222222/command-center/evidence/delivery_investment?projectId=00000000-0000-4000-8000-000000000006",
      "id": "delivery_investment",
      "status": "warn",
      "summary": "No contracted value",
      "title": "Delivery Investment",
      "value": null
    },
    {
      "availability": "unavailable",
      "context": "Scope expansion needs both an engagement start date and normalized work items.",
      "evidenceCount": 0,
      "evidencePath": "/workspaces/22222222-2222-4222-8222-222222222222/command-center/evidence/scope_expansion?projectId=00000000-0000-4000-8000-000000000006",
      "id": "scope_expansion",
      "status": "warn",
      "summary": "No engagement baseline",
      "title": "Scope expansion",
      "value": null
    },
    {
      "availability": "unavailable",
      "context": "Connect a tracker and code host, or import normalized delivery evidence.",
      "evidenceCount": 0,
      "evidencePath": "/workspaces/22222222-2222-4222-8222-222222222222/command-center/evidence/delivery_output?projectId=00000000-0000-4000-8000-000000000006",
      "id": "delivery_output",
      "status": "warn",
      "summary": "No delivery records",
      "title": "Project forensics",
      "value": null
    },
    {
      "availability": "unavailable",
      "context": "Objectives are currently represented by normalized epic-type work items.",
      "evidenceCount": 0,
      "evidencePath": "/workspaces/22222222-2222-4222-8222-222222222222/command-center/evidence/objectives?projectId=00000000-0000-4000-8000-000000000006",
      "id": "objectives",
      "status": "warn",
      "summary": "No tracker data",
      "title": "Objectives",
      "value": null
    },
    {
      "availability": "unavailable",
      "context": "No merged PR or MR carries a self-reported AI-assisted signal, so there is nothing to compare against the non-assisted baseline.",
      "evidenceCount": 0,
      "evidencePath": "/workspaces/22222222-2222-4222-8222-222222222222/command-center/evidence/ai_net_gain?projectId=00000000-0000-4000-8000-000000000006",
      "id": "ai_net_gain",
      "status": "ai",
      "summary": "No AI-assisted merges",
      "title": "AI net delivery gain",
      "value": null
    }
  ],
  "readiness": {
    "canManage": true,
    "costInputs": {
      "rates": 0,
      "timeEntries": 0
    },
    "evidence": {
      "codeChanges": {
        "firstAt": null,
        "inferredLinks": 0,
        "inPeriod": 0,
        "lastAt": null,
        "lastRefreshedAt": null,
        "linkedToWorkItems": 0,
        "merged": 0,
        "open": 0,
        "projectRows": 0,
        "sources": [],
        "unattributedRows": 0
      },
      "workItems": {
        "cancelled": 0,
        "completed": 0,
        "firstAt": null,
        "inPeriod": 0,
        "inProgress": 0,
        "lastAt": null,
        "lastRefreshedAt": null,
        "projectRows": 0,
        "sources": [],
        "todo": 0,
        "unattributedRows": 0
      }
    },
    "roleBands": false,
    "sources": {
      "calendar": {
        "health": "not_connected",
        "providers": []
      },
      "code": {
        "health": "not_connected",
        "providers": []
      },
      "release": {
        "health": "not_connected",
        "providers": []
      },
      "tracker": {
        "health": "not_connected",
        "providers": []
      }
    }
  },
  "sources": [
    {
      "label": "Contracts",
      "source": "commercial",
      "state": "not_connected"
    },
    {
      "label": "Tracker",
      "source": "tracker",
      "state": "not_connected"
    },
    {
      "label": "Code",
      "source": "code",
      "state": "not_connected"
    },
    {
      "label": "Releases",
      "source": "release",
      "state": "not_connected"
    },
    {
      "label": "Calendar",
      "source": "calendar",
      "state": "not_connected"
    }
  ],
  "state": "degraded"
}

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/command-center" \
  --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/command-center", {
  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/command-center", 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.

Inspect a KPI evidence family

Operation: commandCenter.evidence · GET /command-center/evidence/:family

Trace one named Command Center family back to its bounded evidence items. Requires projectId and a supported family path value. This endpoint covers only the five published families, not other internal evidence routes. It shares the Command Center date-window policy and returns availability and explanation with the evidence. Evidence items are the service's bounded drilldown, not a cursor-paginated raw provider export. Preserve null, unavailable and partial evidence, source provenance, confidence qualifiers and currency units; absent evidence is not zero. Dates are civil dates in the supplied IANA zone. No individual performance ranking is returned. Requires a current workspace member, this operation's exact key scope and current creator permission. Invalid filters return 400; missing or foreign resources return 404; missing permission or an effective plan restriction returns 403. Revoked or expired keys return 401; throttled requests return 429 with Retry-After.

Required key scope: command-center:read. Current creator action: command_center.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.

  • start, end and tz travel together; start must not follow end.

  • tz must be a recognized IANA time zone; explicit historical dates remain subject to the current effective reporting window.

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

View schema or synthetic response
JSON

[
  {
    "example": "delivery_output",
    "in": "path",
    "name": "family",
    "required": true,
    "schema": {
      "enum": [
        "delivery_investment",
        "scope_expansion",
        "delivery_output",
        "objectives",
        "ai_net_gain"
      ],
      "type": "string"
    }
  },
  {
    "example": "11111111-1111-4111-8111-111111111111",
    "in": "query",
    "name": "projectId",
    "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": "2026-10-01", "in": "query", "name": "start", "required": false, "schema": { "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" } }, { "example": "2026-10-07", "in": "query", "name": "end", "required": false, "schema": { "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" } }, { "example": "UTC", "in": "query", "name": "tz", "required": false, "schema": { "maxLength": 64, "minLength": 1, "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

{
  "evidence": [],
  "explanation": "Normalized work items, pull requests or merge requests, and releases counted for this project.",
  "family": "delivery_output",
  "title": "Project forensics"
}

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/command-center/evidence/delivery_output?projectId=11111111-1111-4111-8111-111111111111&start=2026-10-01&end=2026-10-07&tz=UTC" \
  --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/command-center/evidence/delivery_output?projectId=11111111-1111-4111-8111-111111111111&start=2026-10-01&end=2026-10-07&tz=UTC", {
  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/command-center/evidence/delivery_output?projectId=11111111-1111-4111-8111-111111111111&start=2026-10-01&end=2026-10-07&tz=UTC", 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.

Read the searchable evidence corpus

Operation: search.read · GET /search

Build a safe corpus for a customer's own search interface. Returns grouped metadata, evidence facts and destination actions; the app ranks text locally and the server does not collect the search term. Optional client/project filters bound directory and report rows as well as facts; workspace connection rows are omitted for a project/client-filtered corpus. Start/end are paired; UTC is the default zone. Groups are bounded by the domain service; no server search or cursor pagination is promised. Preserve null, unavailable and partial evidence, source provenance, confidence qualifiers and currency units; absent evidence is not zero. Dates are civil dates in the supplied IANA zone. No individual performance ranking is returned. Requires a current workspace member, this operation's exact key scope and current creator permission. Invalid filters return 400; missing or foreign resources return 404; missing permission or an effective plan restriction returns 403. Revoked or expired keys return 401; throttled requests return 429 with Retry-After.

Required key scope: command-center:read. Current creator action: command_center.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.

  • start and end are paired and ordered; tz is optional and defaults to UTC.

  • A supplied project must belong to a supplied client; all returned customer datasets follow the selection.

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

View schema or synthetic response
JSON

[
  {
    "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" } }, { "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": "start", "required": false, "schema": { "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" } }, { "in": "query", "name": "end", "required": false, "schema": { "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" } }, { "in": "query", "name": "tz", "required": false, "schema": { "maxLength": 64, "minLength": 1, "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

{
  "canManageSources": true,
  "facts": {
    "aiAssistedChanges": null,
    "aiNetHours": null,
    "changeRequestReference": null,
    "scopeSignals": null,
    "scopeValue": null
  },
  "groups": [
    {
      "items": [
        {
          "action": {
            "type": "goto",
            "view": "sources"
          },
          "icon": "meeting",
          "id": "insight-coverage:commercial",
          "keywords": "Report coverage is limited by contracts — not connected 0 of 5 sources reporting",
          "kind": "insight",
          "meta": "0 of 5 sources reporting",
          "section": "insights",
          "title": "Report coverage is limited by contracts — not connected",
          "tone": "warn"
        },
        {
          "action": {
            "type": "goto",
            "view": "sources"
          },
          "icon": "meeting",
          "id": "insight-coverage:tracker",
          "keywords": "Report coverage is limited by tracker — not connected 0 of 5 sources reporting",
          "kind": "insight",
          "meta": "0 of 5 sources reporting",
          "section": "insights",
          "title": "Report coverage is limited by tracker — not connected",
          "tone": "warn"
        },
        {
          "action": {
            "type": "goto",
            "view": "sources"
          },
          "icon": "meeting",
          "id": "insight-coverage:code",
          "keywords": "Report coverage is limited by code — not connected 0 of 5 sources reporting",
          "kind": "insight",
          "meta": "0 of 5 sources reporting",
          "section": "insights",
          "title": "Report coverage is limited by code — not connected",
          "tone": "warn"
        },
        {
          "action": {
            "type": "goto",
            "view": "sources"
          },
          "icon": "meeting",
          "id": "insight-coverage:release",
          "keywords": "Report coverage is limited by releases — not connected 0 of 5 sources reporting",
          "kind": "insight",
          "meta": "0 of 5 sources reporting",
          "section": "insights",
          "title": "Report coverage is limited by releases — not connected",
          "tone": "warn"
        },
        {
          "action": {
            "type": "goto",
            "view": "sources"
          },
          "icon": "meeting",
          "id": "insight-coverage:calendar",
          "keywords": "Report coverage is limited by calendar — not connected 0 of 5 sources reporting",
          "kind": "insight",
          "meta": "0 of 5 sources reporting",
          "section": "insights",
          "title": "Report coverage is limited by calendar — not connected",
          "tone": "warn"
        }
      ],
      "section": "insights"
    },
    {
      "items": [
        {
          "action": {
            "clientId": "00000000-0000-4000-8000-000000000005",
            "type": "client"
          },
          "glyph": {
            "glyph": "HB",
            "tone": "amber"
          },
          "id": "client-00000000-0000-4000-8000-000000000005",
          "keywords": "Hidden by selection 1 active project client",
          "kind": "client",
          "meta": "1 active project",
          "section": "clients",
          "title": "Hidden by selection"
        },
        {
          "action": {
            "clientId": "33333333-3333-4333-8333-333333333333",
            "type": "client"
          },
          "glyph": {
            "glyph": "SV",
            "tone": "teal"
          },
          "id": "client-33333333-3333-4333-8333-333333333333",
          "keywords": "Synthetic visible client 1 active project client",
          "kind": "client",
          "meta": "1 active project",
          "section": "clients",
          "title": "Synthetic visible client"
        }
      ],
      "section": "clients"
    },
    {
      "items": [
        {
          "action": {
            "projectId": "00000000-0000-4000-8000-000000000006",
            "type": "project"
          },
          "icon": "doc",
          "id": "project-00000000-0000-4000-8000-000000000006",
          "keywords": "Hidden by selection Hidden by selection Active project",
          "kind": "project",
          "meta": "Hidden by selection · Active",
          "section": "projects",
          "title": "Hidden by selection"
        },
        {
          "action": {
            "projectId": "11111111-1111-4111-8111-111111111111",
            "type": "project"
          },
          "icon": "doc",
          "id": "project-11111111-1111-4111-8111-111111111111",
          "keywords": "Synthetic visible project Synthetic visible client Active project",
          "kind": "project",
          "meta": "Synthetic visible client · Active",
          "section": "projects",
          "title": "Synthetic visible project"
        }
      ],
      "section": "projects"
    }
  ]
}

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/search" \
  --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/search", {
  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/search", 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.

Read a project's evidence graph

Operation: forensics.read · GET /projects/:projectId/forensics

Inspect a project's evidence graph, custody and engagement lock for a required ordered date range. UTC is the default timezone. A project without an engagement returns a null graph rather than an invented lock or cost. The complete domain graph is one response, with no pagination. Projection, grouping and scope-lock mutations remain separate internal operations. Preserve null, unavailable and partial evidence, source provenance, confidence qualifiers and currency units; absent evidence is not zero. Dates are civil dates in the supplied IANA zone. No individual performance ranking is returned. Requires a current workspace member, this operation's exact key scope and current creator permission. Invalid filters return 400; missing or foreign resources return 404; missing permission or an effective plan restriction returns 403. Revoked or expired keys return 401; throttled requests return 429 with Retry-After.

Required key scope: forensics:read. Current creator action: forensics.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.

  • start must not follow end; tz must be a recognized IANA time zone and defaults to UTC.

  • The effective plan's historical reporting window is enforced before reading evidence.

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

View schema or synthetic response
JSON

[
  {
    "example": "11111111-1111-4111-8111-111111111111",
    "in": "path",
    "name": "projectId",
    "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": "2026-10-01", "in": "query", "name": "start", "required": true, "schema": { "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" } }, { "example": "2026-10-07", "in": "query", "name": "end", "required": true, "schema": { "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" } }, { "example": "UTC", "in": "query", "name": "tz", "required": false, "schema": { "maxLength": 64, "minLength": 1, "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

{
  "engagement": null,
  "graph": null,
  "lock": null,
  "period": {
    "end": "2026-10-01",
    "start": "2026-10-01",
    "timeZone": "UTC"
  },
  "project": {
    "clientName": "Synthetic visible client",
    "id": "11111111-1111-4111-8111-111111111111",
    "name": "Synthetic visible project"
  }
}

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/projects/11111111-1111-4111-8111-111111111111/forensics?start=2026-10-01&end=2026-10-07&tz=UTC" \
  --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/projects/11111111-1111-4111-8111-111111111111/forensics?start=2026-10-01&end=2026-10-07&tz=UTC", {
  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/projects/11111111-1111-4111-8111-111111111111/forensics?start=2026-10-01&end=2026-10-07&tz=UTC", 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.

Read scope expansion evidence

Operation: scope.read · GET /projects/:projectId/scope-creep

Read the selected project's scope baseline, changes and valuation for a required ordered date range. UTC is the default timezone. A project without an engagement has a null report; uncertain attribution and unsupported valuation remain explicit. This is a single derived report rather than a paginated work-item export, and it does not create a change-request narrative. Preserve null, unavailable and partial evidence, source provenance, confidence qualifiers and currency units; absent evidence is not zero. Dates are civil dates in the supplied IANA zone. No individual performance ranking is returned. Requires a current workspace member, this operation's exact key scope and current creator permission. Invalid filters return 400; missing or foreign resources return 404; missing permission or an effective plan restriction returns 403. Revoked or expired keys return 401; throttled requests return 429 with Retry-After.

Required key scope: scope-creep:read. Current creator action: scope.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.

  • start must not follow end; tz must be a recognized IANA time zone and defaults to UTC.

  • The effective plan's historical reporting window is enforced before reading evidence.

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

View schema or synthetic response
JSON

[
  {
    "example": "11111111-1111-4111-8111-111111111111",
    "in": "path",
    "name": "projectId",
    "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": "2026-10-01", "in": "query", "name": "start", "required": true, "schema": { "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" } }, { "example": "2026-10-07", "in": "query", "name": "end", "required": true, "schema": { "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" } }, { "example": "UTC", "in": "query", "name": "tz", "required": false, "schema": { "maxLength": 64, "minLength": 1, "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

{
  "engagement": null,
  "lock": null,
  "project": {
    "clientName": "Synthetic visible client",
    "id": "11111111-1111-4111-8111-111111111111",
    "name": "Synthetic visible project"
  },
  "report": null
}

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/projects/11111111-1111-4111-8111-111111111111/scope-creep?start=2026-10-01&end=2026-10-07&tz=UTC" \
  --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/projects/11111111-1111-4111-8111-111111111111/scope-creep?start=2026-10-01&end=2026-10-07&tz=UTC", {
  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/projects/11111111-1111-4111-8111-111111111111/scope-creep?start=2026-10-01&end=2026-10-07&tz=UTC", 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.

Reconcile invoice facts with delivery

Operation: invoiceDefense.read · GET /invoice-defense

Read deterministic delivery facts and reconcile the latest invoice overlapping a required project date range. Optional question selects a supported explanation pack. Missing invoices or prerequisites remain null. The public GET always uses facts mode and never invokes a narrative model or charges an AI request. Invoice amounts are minor currency units. No invoice write or pagination is provided. Preserve null, unavailable and partial evidence, source provenance, confidence qualifiers and currency units; absent evidence is not zero. Dates are civil dates in the supplied IANA zone. No individual performance ranking is returned. Requires a current workspace member, this operation's exact key scope and current creator permission. Invalid filters return 400; missing or foreign resources return 404; missing permission or an effective plan restriction returns 403. Revoked or expired keys return 401; throttled requests return 429 with Retry-After.

Required key scope: invoice-defense:read. Current creator action: invoice_defense.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.

  • start must not follow end; tz must be a recognized IANA time zone and defaults to UTC.

  • Public reads always return deterministic facts without narrative model execution.

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": 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": "2026-10-01", "in": "query", "name": "start", "required": true, "schema": { "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" } }, { "example": "2026-10-07", "in": "query", "name": "end", "required": true, "schema": { "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" } }, { "example": "UTC", "in": "query", "name": "tz", "required": false, "schema": { "maxLength": 64, "minLength": 1, "type": "string" } }, { "in": "query", "name": "question", "required": false, "schema": { "maxLength": 120, "type": "string" } }, { "example": "facts", "in": "query", "name": "mode", "required": false, "schema": { "enum": [ "facts" ], "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

{
  "facts": {
    "actions": [
      {
        "action": "Review added items with the client and formalize the next-cycle scope.",
        "n": 1,
        "tag": "Margin",
        "title": "Convert scope expansion into a change request",
        "tone": "amber",
        "why": "No scope baseline is recorded for this period yet."
      },
      {
        "action": "Create a dedicated discovery / clarification budget bucket.",
        "n": 2,
        "tag": "Process",
        "title": "Separate discovery from implementation budget",
        "tone": "blue",
        "why": "Clarification meetings are not yet attributed to this project."
      },
      {
        "action": "Require ticket IDs in branch names and PR titles.",
        "n": 3,
        "tag": "Data",
        "title": "Improve ticket-to-PR traceability",
        "tone": "neutral",
        "why": "No merged PRs were recorded in this period."
      },
      {
        "action": "Add an AI-assisted field or label to relevant work items.",
        "n": 4,
        "tag": "AI",
        "title": "Track AI-assisted work explicitly",
        "tone": "purple",
        "why": "AI-assisted delivery cannot be measured until assisted work is tagged."
      },
      {
        "action": "Use the executive summary and scope expansion sections in the next QBR or invoice discussion.",
        "n": 5,
        "tag": "Client",
        "title": "Use this report in the next client review",
        "tone": "green",
        "why": "The report provides a shared view of shipped work, cost, scope movement, and risks — useful for QBRs, retainer reviews, and invoice discussions."
      }
    ],
    "ai": null,
    "aiInsufficientSample": null,
    "assumptions": [
      {
        "effectiveFrom": "2026-10-01",
        "effectiveTo": null,
        "id": "cost-basis",
        "source": "default",
        "status": "needs_verification",
        "title": "Cost estimate basis",
        "unitOrMethod": "person_then_role",
        "value": "No rate card",
        "versionId": null
      },
      {
        "effectiveFrom": "2026-10-01",
        "effectiveTo": null,
        "id": "scope-baseline",
        "source": "default",
        "status": "needs_verification",
        "title": "Scope baseline",
        "unitOrMethod": "engagement_start",
        "value": "0 work items",
        "versionId": null
      },
      {
        "effectiveFrom": "2026-10-01",
        "effectiveTo": null,
        "id": "meeting-attribution",
        "source": "default",
        "status": "needs_verification",
        "title": "Meeting attribution",
        "unitOrMethod": "project_tagged",
        "value": "No meetings synced",
        "versionId": null
      },
      {
        "effectiveFrom": "2026-10-01",
        "effectiveTo": null,
        "id": "ai-attribution",
        "source": "default",
        "status": "needs_verification",
        "title": "AI attribution",
        "unitOrMethod": "self_reported",
        "value": "Self-reported labels and trailers",
        "versionId": null
      },
      {
        "effectiveFrom": "2026-10-01",
        "effectiveTo": null,
        "id": "reporting-period",
        "source": "default",
        "status": "needs_verification",
        "title": "Reporting period",
        "unitOrMethod": "active_range",
        "value": "Oct 1, 2026",
        "versionId": null
      },
      {
        "effectiveFrom": "2026-10-01",
        "effectiveTo": null,
        "id": "work-cost-allocation",
        "source": "default",
        "status": "needs_verification",
        "title": "Work-item cost allocation",
        "unitOrMethod": "not_allocated",
        "value": "Team estimate only",
        "versionId": null
      }
    ],
    "confidence": {
      "hints": [
        "Include ticket IDs in pull-request titles or branch names.",
        "Map tracker work items to the client and project.",
        "Tag calendar events with the client or project.",
        "Add person-level rates for worked hours; role rates remain partial.",
        "Explicitly mark AI-assisted merged work with labels or commit trailers.",
        "Connect deployment evidence to completed work items.",
        "Connect a source or import evidence consistently to reduce manual-only coverage.",
        "Reconnect or sync sources so their latest successful data is current.",
        "Confirm or rectify the reporting assumptions used for this period."
      ],
      "label": "Low",
      "score": 0,
      "signals": [
        {
          "contribution": null,
          "evidence": {
            "denominator": 0,
            "numerator": 0,
            "query": "Merged code changes linked to normalized work items in the report period."
          },
          "id": "prs_linked",
          "label": "PRs linked to tickets",
          "note": "No merged PRs yet",
          "pct": null,
          "weight": 16
        },
        {
          "contribution": null,
          "evidence": {
            "denominator": 0,
            "numerator": 0,
            "query": "Workspace work items in the report period with a normalized project mapping."
          },
          "id": "items_mapped",
          "label": "Tickets mapped to client / project",
          "note": "Workspace mapping coverage",
          "pct": null,
          "weight": 14
        },
        {
          "contribution": null,
          "evidence": {
            "denominator": null,
            "numerator": null,
            "query": "An active Google Calendar connection is required before calendar tagging is measured."
          },
          "id": "meetings_tagged",
          "label": "Meetings tagged to client / project",
          "note": "No active calendar source",
          "pct": null,
          "weight": 12
        },
        {
          "contribution": null,
          "evidence": {
            "denominator": 0,
            "numerator": 0,
            "query": "Project time entries priced by person-level rates (100%) or role-level rates (60%)."
          },
          "id": "rate_card",
          "label": "Rate card precision",
          "note": "No labour hours in this period",
          "pct": null,
          "weight": 14
        },
        {
          "contribution": null,
          "evidence": {
            "denominator": null,
            "numerator": null,
            "query": "Explicit self-reported AI labels or commit trailers on merged changes."
          },
          "id": "ai_tagging",
          "label": "AI-assisted work tagging",
          "note": "Not tagged",
          "pct": null,
          "weight": 12
        },
        {
          "contribution": null,
          "evidence": {
            "denominator": 0,
            "numerator": 0,
            "query": "Completed project work items linked to a merged change and a release through explicit evidence links."
          },
          "id": "release_evidence",
          "label": "Release / deployment evidence",
          "note": "Completed work with linked release evidence",
          "pct": null,
          "weight": 10
        },
        {
          "contribution": null,
          "evidence": {
            "denominator": null,
            "numerator": null,
            "query": "Synced rather than manual or CSV evidence rows in the report context."
          },
          "id": "manual_entry_share",
          "label": "Synced evidence share",
          "note": "Synced evidence coverage",
          "pct": null,
          "weight": 8
        },
        {
          "contribution": null,
          "evidence": {
            "denominator": 0,
            "numerator": 0,
            "query": "Latest successful sync per active connection, measured against the report period end."
          },
          "id": "freshness",
          "label": "Source freshness",
          "note": "No active sources",
          "pct": null,
          "weight": 8
        },
        {
          "contribution": 0,
          "evidence": {
            "denominator": 6,
            "numerator": 0,
            "query": "Resolved confirmed or rectified report assumptions at the workspace, client, project, and reporting-period scope."
          },
          "id": "assumptions",
          "label": "Confirmed reporting assumptions",
          "note": "0 of 6 reporting assumptions are confirmed or rectified for this period.",
          "pct": 0,
          "weight": 6
        }
      ]
    },
    "coordination": {
      "blendedHourlyRateCents": null,
      "costCents": null,
      "declined": 0,
      "hours": 0,
      "meetings": 0,
      "taggingPct": null
    },
    "currency": null,
    "delivery": {
      "completedItems": 0,
      "mergedChanges": 0,
      "milestones": 0,
      "objectivesCompleted": 0,
      "objectivesTotal": 0,
      "prsLinkedPct": null,
      "releaseRows": [],
      "releases": 0,
      "rows": []
    },
    "evidencePackages": [],
    "investment": {
      "cloudCents": 0,
      "coordinationCents": null,
      "coordinationPct": null,
      "costEvidence": {
        "cloudLines": 0,
        "linkedTimeEntries": 0,
        "timeEntries": 0
      },
      "currencyConflict": false,
      "estimated": false,
      "estimatedCloudCents": 0,
      "invoicedCents": null,
      "labourCategories": [],
      "labourCents": 0,
      "labourHours": 0,
      "reworkCents": null,
      "reworkPct": null,
      "roleBandHours": 0,
      "scopeCents": null,
      "scopePct": null,
      "totalCents": null,
      "unpricedHours": 0
    },
    "manualEntrySharePct": null,
    "periodEnd": "2026-10-01",
    "periodStart": "2026-10-01",
    "scope": null,
    "sources": [
      {
        "label": "Contracts",
        "source": "commercial",
        "state": "not_connected"
      },
      {
        "label": "Tracker",
        "source": "tracker",
        "state": "not_connected"
      },
      {
        "label": "Code",
        "source": "code",
        "state": "not_connected"
      },
      {
        "label": "Releases",
        "source": "release",
        "state": "not_connected"
      },
      {
        "label": "Calendar",
        "source": "calendar",
        "state": "not_connected"
      }
    ]
  },
  "invoice": null,
  "pack": null,
  "reconciliation": null
}

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/invoice-defense?projectId=11111111-1111-4111-8111-111111111111&start=2026-10-01&end=2026-10-07&tz=UTC&mode=facts" \
  --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/invoice-defense?projectId=11111111-1111-4111-8111-111111111111&start=2026-10-01&end=2026-10-07&tz=UTC&mode=facts", {
  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/invoice-defense?projectId=11111111-1111-4111-8111-111111111111&start=2026-10-01&end=2026-10-07&tz=UTC&mode=facts", 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.

Read measured AI economics

Operation: aiEconomics.read · GET /ai-economics

Read source-reported AI usage, adoption and measured cycle-time comparisons for an accessible project or client selection. Dates use the same effective reporting window as Command Center. Assistance tags are self-reported and comparisons are observational, not a causal productivity claim. Currency conversions and missing prices remain explicit. Returns one aggregate response with no person ranking or pagination. Preserve null, unavailable and partial evidence, source provenance, confidence qualifiers and currency units; absent evidence is not zero. Dates are civil dates in the supplied IANA zone. No individual performance ranking is returned. Requires a current workspace member, this operation's exact key scope and current creator permission. Invalid filters return 400; missing or foreign resources return 404; missing permission or an effective plan restriction returns 403. Revoked or expired keys return 401; throttled requests return 429 with Retry-After.

Required key scope: ai-economics:read. Current creator action: ai_economics.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.

  • start, end and tz travel together; start must not follow end.

  • tz must be a recognized IANA time zone; explicit historical dates remain subject to the current effective reporting window.

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

View schema or synthetic response
JSON

[
  {
    "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" } }, { "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": "start", "required": false, "schema": { "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" } }, { "in": "query", "name": "end", "required": false, "schema": { "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" } }, { "in": "query", "name": "tz", "required": false, "schema": { "maxLength": 64, "minLength": 1, "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

{
  "adoption": {
    "assistedChanges": 0,
    "basis": "merged changes counted by self-reported AI tags",
    "byRepository": [],
    "byWorkType": [],
    "conflictingChanges": 0,
    "mergedChanges": 0,
    "notAssistedChanges": 0,
    "provenance": "self_reported",
    "taggedEvidence": [],
    "taggedEvidenceTotal": 0,
    "tools": [],
    "untaggedChanges": 0,
    "workTypeLinks": {
      "byOrigin": {
        "connector": 0,
        "heuristic": 0,
        "manual": 0
      },
      "linkedChanges": 0
    }
  },
  "cycleTime": {
    "assistedChanges": 0,
    "baselineChanges": 0,
    "gain": null,
    "unavailableReason": "No merged self-reported AI-assisted changes have complete forge timestamps."
  },
  "usage": {
    "assumptions": [],
    "selfReported": {
      "assistedChanges": 0,
      "assistedShare": null,
      "conflictingChanges": 0,
      "notAssistedChanges": 0,
      "taggedChanges": 0,
      "tools": []
    },
    "unavailable": [],
    "vendors": [],
    "vendorWindowSelection": null
  }
}

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/ai-economics" \
  --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/ai-economics", {
  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/ai-economics", 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.

Read interpreted AI economics

Operation: aiEconomics.surface · GET /ai-economics/surface

Read the serializable interpretation used by the AI Economics screen, including unavailable states and confidence when a project and reporting period are selected. It uses exactly the same source facts and reporting window as the AI economics facts endpoint. Null or insufficient comparisons must retain their qualifier. This is a single response without pagination. Preserve null, unavailable and partial evidence, source provenance, confidence qualifiers and currency units; absent evidence is not zero. Dates are civil dates in the supplied IANA zone. No individual performance ranking is returned. Requires a current workspace member, this operation's exact key scope and current creator permission. Invalid filters return 400; missing or foreign resources return 404; missing permission or an effective plan restriction returns 403. Revoked or expired keys return 401; throttled requests return 429 with Retry-After.

Required key scope: ai-economics:read. Current creator action: ai_economics.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.

  • start, end and tz travel together; start must not follow end.

  • tz must be a recognized IANA time zone; explicit historical dates remain subject to the current effective reporting window.

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

View schema or synthetic response
JSON

[
  {
    "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" } }, { "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": "start", "required": false, "schema": { "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" } }, { "in": "query", "name": "end", "required": false, "schema": { "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" } }, { "in": "query", "name": "tz", "required": false, "schema": { "maxLength": 64, "minLength": 1, "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

{
  "adoption": {
    "assistedChanges": 0,
    "basis": "merged changes counted by self-reported AI tags",
    "byRepository": [],
    "byWorkType": [],
    "conflictingChanges": 0,
    "mergedChanges": 0,
    "notAssistedChanges": 0,
    "provenance": "self_reported",
    "taggedEvidence": [],
    "taggedEvidenceTotal": 0,
    "tools": [],
    "untaggedChanges": 0,
    "workTypeLinks": {
      "byOrigin": {
        "connector": 0,
        "heuristic": 0,
        "manual": 0
      },
      "linkedChanges": 0
    }
  },
  "comparison": {
    "assistedChanges": 0,
    "baselineChanges": 0,
    "basis": "observed forge timestamps compared by self-reported AI tagging",
    "implementationHoursSaved": null,
    "inputProvenance": "self_reported",
    "kind": "modeled_counterfactual",
    "netDeliveryGainHours": null,
    "reviewOverheadHours": null,
    "sample": {
      "mergedChanges": 0,
      "minimumPerGroup": 10,
      "minimumTaggingCoverage": 0.1,
      "taggedChanges": 0,
      "taggingCoverage": null
    },
    "state": "unavailable",
    "unavailableReason": "No merged self-reported AI-assisted changes have complete forge timestamps."
  },
  "models": {
    "reason": "No aggregate provider windows are available to establish model usage.",
    "state": "unavailable"
  },
  "providerWindows": {
    "description": "Provider-reported aggregates are shown in their complete source reporting windows.",
    "requestedPeriod": null,
    "state": "unavailable",
    "windows": []
  },
  "reportConfidence": {
    "reason": "Report confidence requires a selected project and finite reporting period.",
    "state": "unavailable"
  },
  "reviewOverhead": {
    "reason": "The reader has no work-type dimension for review overhead; it will not infer one from aggregate usage or timestamps.",
    "state": "unavailable"
  },
  "selfReportedAdoption": {
    "assistedChanges": 0,
    "assistedShare": null,
    "conflictingChanges": 0,
    "notAssistedChanges": 0,
    "provenance": "self_reported",
    "taggedChanges": 0,
    "tools": []
  },
  "subtitle": "A modeled comparison of observed forge timestamps alongside aggregate provider data.",
  "title": "AI delivery economics"
}

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/ai-economics/surface" \
  --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/ai-economics/surface", {
  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/ai-economics/surface", 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.

Read report confidence and setup evidence

Operation: confidence.read · GET /confidence

Read a project's report confidence signals and evidence-backed setup checklist. Requires projectId and start/end/tz together; the current effective plan limits the reporting window. Missing signals remain null, and checklist providers explain where setup can improve evidence. The response is a single checklist, not a measure of individual performance or a paginated evidence export. Preserve null, unavailable and partial evidence, source provenance, confidence qualifiers and currency units; absent evidence is not zero. Dates are civil dates in the supplied IANA zone. No individual performance ranking is returned. Requires a current workspace member, this operation's exact key scope and current creator permission. Invalid filters return 400; missing or foreign resources return 404; missing permission or an effective plan restriction returns 403. Revoked or expired keys return 401; throttled requests return 429 with Retry-After.

Required key scope: report-confidence:read. Current creator action: assumptions.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.

  • start, end and tz travel together; start must not follow end.

  • tz must be a recognized IANA time zone; explicit historical dates remain subject to the current effective reporting window.

  • projectId and the complete reporting period are required.

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": 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": "2026-10-01", "in": "query", "name": "start", "required": false, "schema": { "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" } }, { "example": "2026-10-07", "in": "query", "name": "end", "required": false, "schema": { "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" } }, { "example": "UTC", "in": "query", "name": "tz", "required": false, "schema": { "maxLength": 64, "minLength": 1, "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

{
  "checklist": [
    {
      "done": false,
      "id": "ticket-pr-convention",
      "meta": "No merged pull requests in this period",
      "providers": []
    },
    {
      "done": false,
      "id": "project-mapping",
      "meta": "No work items in this period",
      "providers": []
    },
    {
      "done": false,
      "id": "calendar-tags",
      "meta": "No active calendar source",
      "providers": []
    },
    {
      "done": false,
      "id": "scope-lock",
      "meta": "Set an engagement scope lock",
      "providers": []
    },
    {
      "done": false,
      "id": "ai-marking",
      "meta": "No explicitly tagged merged changes",
      "providers": []
    },
    {
      "done": false,
      "evidence": {
        "denominator": 0,
        "numerator": 0,
        "query": "Selected-project work items created, updated or completed in the report UTC period; normalized type other is unclassified."
      },
      "id": "work-type-classification",
      "meta": "No work items in this period",
      "providers": []
    }
  ],
  "confidence": {
    "hints": [
      "Include ticket IDs in pull-request titles or branch names.",
      "Map tracker work items to the client and project.",
      "Tag calendar events with the client or project.",
      "Add person-level rates for worked hours; role rates remain partial.",
      "Explicitly mark AI-assisted merged work with labels or commit trailers.",
      "Connect deployment evidence to completed work items.",
      "Connect a source or import evidence consistently to reduce manual-only coverage.",
      "Reconnect or sync sources so their latest successful data is current.",
      "Confirm or rectify the reporting assumptions used for this period."
    ],
    "label": "Low",
    "score": 0,
    "signals": [
      {
        "contribution": null,
        "evidence": {
          "denominator": 0,
          "numerator": 0,
          "query": "Merged code changes linked to normalized work items in the report period."
        },
        "id": "prs_linked",
        "label": "PRs linked to tickets",
        "note": "No merged PRs yet",
        "pct": null,
        "weight": 16
      },
      {
        "contribution": null,
        "evidence": {
          "denominator": 0,
          "numerator": 0,
          "query": "Workspace work items in the report period with a normalized project mapping."
        },
        "id": "items_mapped",
        "label": "Tickets mapped to client / project",
        "note": "Workspace mapping coverage",
        "pct": null,
        "weight": 14
      },
      {
        "contribution": null,
        "evidence": {
          "denominator": null,
          "numerator": null,
          "query": "An active Google Calendar connection is required before calendar tagging is measured."
        },
        "id": "meetings_tagged",
        "label": "Meetings tagged to client / project",
        "note": "No active calendar source",
        "pct": null,
        "weight": 12
      },
      {
        "contribution": null,
        "evidence": {
          "denominator": 0,
          "numerator": 0,
          "query": "Project time entries priced by person-level rates (100%) or role-level rates (60%)."
        },
        "id": "rate_card",
        "label": "Rate card precision",
        "note": "No labour hours in this period",
        "pct": null,
        "weight": 14
      },
      {
        "contribution": null,
        "evidence": {
          "denominator": null,
          "numerator": null,
          "query": "Explicit self-reported AI labels or commit trailers on merged changes."
        },
        "id": "ai_tagging",
        "label": "AI-assisted work tagging",
        "note": "Not tagged",
        "pct": null,
        "weight": 12
      },
      {
        "contribution": null,
        "evidence": {
          "denominator": 0,
          "numerator": 0,
          "query": "Completed project work items linked to a merged change and a release through explicit evidence links."
        },
        "id": "release_evidence",
        "label": "Release / deployment evidence",
        "note": "Completed work with linked release evidence",
        "pct": null,
        "weight": 10
      },
      {
        "contribution": null,
        "evidence": {
          "denominator": null,
          "numerator": null,
          "query": "Synced rather than manual or CSV evidence rows in the report context."
        },
        "id": "manual_entry_share",
        "label": "Synced evidence share",
        "note": "Synced evidence coverage",
        "pct": null,
        "weight": 8
      },
      {
        "contribution": null,
        "evidence": {
          "denominator": 0,
          "numerator": 0,
          "query": "Latest successful sync per active connection, measured against the report period end."
        },
        "id": "freshness",
        "label": "Source freshness",
        "note": "No active sources",
        "pct": null,
        "weight": 8
      },
      {
        "contribution": 0,
        "evidence": {
          "denominator": 6,
          "numerator": 0,
          "query": "Resolved confirmed or rectified report assumptions at the workspace, client, project, and reporting-period scope."
        },
        "id": "assumptions",
        "label": "Confirmed reporting assumptions",
        "note": "0 of 6 reporting assumptions are confirmed or rectified for this period.",
        "pct": 0,
        "weight": 6
      }
    ]
  }
}

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/confidence?projectId=11111111-1111-4111-8111-111111111111&start=2026-10-01&end=2026-10-07&tz=UTC" \
  --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/confidence?projectId=11111111-1111-4111-8111-111111111111&start=2026-10-01&end=2026-10-07&tz=UTC", {
  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/confidence?projectId=11111111-1111-4111-8111-111111111111&start=2026-10-01&end=2026-10-07&tz=UTC", 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.

Read workspace commercial settings

Operation: commercial.read · GET /settings/organization

Inspect redacted workspace settings, commercial defaults, pinned residency and enforced lifecycle/data-window policy. Requires the existing workspace.manage permission in addition to the cost-model read scope. Unsupported controls include their availability reason. No secret forwarding headers or provider keys are returned. The response is a settings snapshot with no pagination; this endpoint changes no settings. Preserve null, unavailable and partial evidence, source provenance, confidence qualifiers and currency units; absent evidence is not zero. Dates are civil dates in the supplied IANA zone. No individual performance ranking is returned. Requires a current workspace member, this operation's exact key scope and current creator permission. Invalid filters return 400; missing or foreign resources return 404; missing permission or an effective plan restriction returns 403. Revoked or expired keys return 401; throttled requests return 429 with Retry-After.

Required key scope: cost-model:read. Current creator action: workspace.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.

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

{
  "canDeleteImmediately": false,
  "canEdit": true,
  "dataPolicy": {
    "aiProviders": [],
    "auditRetentionDays": 365,
    "backupRetentionMaxDays": 14,
    "dataWindowDays": 365,
    "deletionGraceDays": 30,
    "exportLinkHours": 24,
    "plan": "growth"
  },
  "deletion": null,
  "footprint": {
    "clients": 2,
    "connections": 0,
    "members": 1,
    "projects": 2,
    "reports": 0
  },
  "identity": {
    "createdAt": "2026-10-01T06:54:37.887Z",
    "createdBy": null,
    "lastEditedAt": null,
    "name": "Read contract fixture",
    "region": "us",
    "residency": "United States",
    "slug": "read-contract-fixture",
    "workspaceId": "22222222-2222-4222-8222-222222222222"
  },
  "role": "owner",
  "settings": {
    "commercial": {
      "billingModel": "Time & Materials",
      "costModel": "Role-based hourly rate",
      "includeAiTooling": true,
      "includeCloudCost": true,
      "includeMeetings": true,
      "includePlanning": true,
      "marginTarget": 35,
      "overhead": 18,
      "rates": {
        "data": 110,
        "design": 90,
        "engineering": 85,
        "engineeringManagement": 120,
        "product": 95,
        "qa": 65
      },
      "rounding": "Nearest $1"
    },
    "defaults": {
      "currency": "USD",
      "fiscalYearStart": "January",
      "focusTarget": 60,
      "hoursPerDay": 8,
      "language": "English",
      "region": "Europe",
      "timeZone": "UTC",
      "utilizationTarget": 75,
      "weeksPerQuarter": 13,
      "workingDays": [
        "Mon",
        "Tue",
        "Wed",
        "Thu",
        "Fri"
      ]
    },
    "identity": {
      "website": ""
    },
    "narrativeAi": {
      "modelOverride": null
    },
    "privacy": {
      "allowCrossRegionAi": false,
      "allowDataExport": true,
      "anonymizeContributors": true,
      "hideMarginFromNonAdmins": true,
      "hideSalaryFromManagers": true,
      "keepReportsInRegion": true,
      "requireApprovalForSources": true,
      "retention": {
        "aggregated": "3 years",
        "audit": "1 year",
        "exports": "90 days",
        "raw": "90 days"
      }
    },
    "security": {
      "auditForwardingEnabled": false,
      "auditForwardingHeaders": [],
      "auditForwardingUrl": "",
      "requireSso": false,
      "requireTwoFactor": false
    }
  },
  "unavailable": {
    "auditForwarding": {
      "available": false,
      "reason": "ScopeWorth has no outbound audit forwarder yet. The audit trail is recorded and readable under Audit, and can be exported from there."
    },
    "dataResidency": {
      "available": false,
      "reason": "The data region is pinned when the workspace is created and cannot be moved; a different region means a different workspace."
    },
    "logo": {
      "available": false,
      "reason": "ScopeWorth does not store organization logos yet; reports and exports use the workspace name."
    },
    "reportRegion": {
      "available": false,
      "reason": "Reports, snapshots and PDFs are generated and stored in this workspace's pinned region. A report that is emailed, shared or downloaded is also held by the email provider and its recipients, so no setting can keep every copy in the region."
    },
    "retention": {
      "available": false,
      "reason": "Retention follows the plan and ScopeWorth's workspace lifecycle, not a per-workspace choice. The data window changes with the plan; audit-log retention is set under Audit."
    },
    "ssoEnforcement": {
      "available": false,
      "reason": "No identity provider is configured for this workspace, and enforcement is refused until at least one admin can sign in through one."
    },
    "twoFactorEnforcement": {
      "available": false,
      "reason": "Two-factor authentication is not enabled on this ScopeWorth cell yet, so it cannot be required of members from here."
    }
  }
}

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/settings/organization" \
  --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/settings/organization", {
  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/settings/organization", 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.

Read connector and import health

Operation: dataSources.read · GET /data-sources

Monitor configured connector health, recent sync runs, dead-letter metadata, imports, scope mappings and non-secret cloud binding summaries. Requires the existing integrations.manage action. Availability reflects the deployed connector registry and setup configuration. Failure or missing evidence stays distinct from zero activity. Recent lists have the existing service bounds and no cursor; credential ciphertext, refresh tokens and provider secrets are excluded. Preserve null, unavailable and partial evidence, source provenance, confidence qualifiers and currency units; absent evidence is not zero. Dates are civil dates in the supplied IANA zone. No individual performance ranking is returned. Requires a current workspace member, this operation's exact key scope and current creator permission. Invalid filters return 400; missing or foreign resources return 404; missing permission or an effective plan restriction returns 403. Revoked or expired keys return 401; throttled requests return 429 with Retry-After.

Required key scope: data-sources:read. Current creator action: integrations.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.

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,
  "catalog": [
    {
      "availability": "coming_soon",
      "category": "delivery",
      "connectUrl": null,
      "label": "Jira",
      "provider": "jira",
      "rateLimit": null,
      "setupKind": null,
      "skippedInSetup": [],
      "supportsConnectionTest": false
    },
    {
      "availability": "coming_soon",
      "category": "delivery",
      "connectUrl": null,
      "label": "Linear",
      "provider": "linear",
      "rateLimit": null,
      "setupKind": null,
      "skippedInSetup": [],
      "supportsConnectionTest": false
    },
    {
      "availability": "coming_soon",
      "category": "delivery",
      "connectUrl": null,
      "label": "Azure DevOps",
      "provider": "azure_devops",
      "rateLimit": null,
      "setupKind": null,
      "skippedInSetup": [],
      "supportsConnectionTest": false
    },
    {
      "availability": "coming_soon",
      "category": "delivery",
      "connectUrl": null,
      "label": "Asana",
      "provider": "asana",
      "rateLimit": null,
      "setupKind": null,
      "skippedInSetup": [],
      "supportsConnectionTest": false
    },
    {
      "availability": "coming_soon",
      "category": "code",
      "connectUrl": null,
      "label": "GitHub",
      "provider": "github",
      "rateLimit": null,
      "setupKind": null,
      "skippedInSetup": [],
      "supportsConnectionTest": false
    },
    {
      "availability": "coming_soon",
      "category": "code",
      "connectUrl": null,
      "label": "GitLab",
      "provider": "gitlab",
      "rateLimit": null,
      "setupKind": null,
      "skippedInSetup": [],
      "supportsConnectionTest": false
    },
    {
      "availability": "coming_soon",
      "category": "code",
      "connectUrl": null,
      "label": "Bitbucket",
      "provider": "bitbucket",
      "rateLimit": null,
      "setupKind": null,
      "skippedInSetup": [],
      "supportsConnectionTest": false
    },
    {
      "availability": "coming_soon",
      "category": "calendar",
      "connectUrl": null,
      "label": "Google Calendar",
      "provider": "google_calendar",
      "rateLimit": null,
      "setupKind": null,
      "skippedInSetup": [],
      "supportsConnectionTest": false
    },
    {
      "availability": "coming_soon",
      "category": "calendar",
      "connectUrl": null,
      "label": "Microsoft 365",
      "provider": "microsoft_365",
      "rateLimit": null,
      "setupKind": null,
      "skippedInSetup": [],
      "supportsConnectionTest": false
    },
    {
      "availability": "coming_soon",
      "category": "communication",
      "connectUrl": null,
      "label": "Slack",
      "provider": "slack",
      "rateLimit": null,
      "setupKind": null,
      "skippedInSetup": [],
      "supportsConnectionTest": false
    },
    {
      "availability": "coming_soon",
      "category": "communication",
      "connectUrl": null,
      "label": "Microsoft Teams",
      "provider": "teams",
      "rateLimit": null,
      "setupKind": null,
      "skippedInSetup": [],
      "supportsConnectionTest": false
    },
    {
      "availability": "coming_soon",
      "category": "ai",
      "connectUrl": null,
      "label": "GitHub Copilot",
      "provider": "copilot",
      "rateLimit": null,
      "setupKind": null,
      "skippedInSetup": [],
      "supportsConnectionTest": false
    },
    {
      "availability": "coming_soon",
      "category": "ai",
      "connectUrl": null,
      "label": "Cursor",
      "provider": "cursor",
      "rateLimit": null,
      "setupKind": null,
      "skippedInSetup": [],
      "supportsConnectionTest": false
    },
    {
      "availability": "coming_soon",
      "category": "ai",
      "connectUrl": null,
      "label": "Claude Code",
      "provider": "claude_code",
      "rateLimit": null,
      "setupKind": null,
      "skippedInSetup": [],
      "supportsConnectionTest": false
    },
    {
      "availability": "coming_soon",
      "category": "ai",
      "connectUrl": null,
      "label": "OpenAI Codex",
      "provider": "codex",
      "rateLimit": null,
      "setupKind": null,
      "skippedInSetup": [],
      "supportsConnectionTest": false
    },
    {
      "availability": "coming_soon",
      "category": "ai",
      "connectUrl": null,
      "label": "Gemini Code Assist",
      "provider": "gemini",
      "rateLimit": null,
      "setupKind": null,
      "skippedInSetup": [],
      "supportsConnectionTest": false
    },
    {
      "availability": "coming_soon",
      "category": "cloud",
      "connectUrl": null,
      "label": "AWS",
      "provider": "aws",
      "rateLimit": null,
      "setupKind": null,
      "skippedInSetup": [],
      "supportsConnectionTest": false
    },
    {
      "availability": "coming_soon",
      "category": "cloud",
      "connectUrl": null,
      "label": "Google Cloud",
      "provider": "gcp",
      "rateLimit": null,
      "setupKind": null,
      "skippedInSetup": [],
      "supportsConnectionTest": false
    },
    {
      "availability": "coming_soon",
      "category": "cloud",
      "connectUrl": null,
      "label": "Microsoft Azure",
      "provider": "azure_cost",
      "rateLimit": null,
      "setupKind": null,
      "skippedInSetup": [],
      "supportsConnectionTest": false
    },
    {
      "availability": "coming_soon",
      "category": "cloud",
      "connectUrl": null,
      "label": "Cloudflare",
      "provider": "cloudflare",
      "rateLimit": null,
      "setupKind": null,
      "skippedInSetup": [],
      "supportsConnectionTest": false
    },
    {
      "availability": "coming_soon",
      "category": "cloud",
      "connectUrl": null,
      "label": "Vercel",
      "provider": "vercel",
      "rateLimit": null,
      "setupKind": null,
      "skippedInSetup": [],
      "supportsConnectionTest": false
    },
    {
      "availability": "available",
      "category": "import",
      "connectUrl": null,
      "label": "CSV import",
      "provider": "csv",
      "rateLimit": null,
      "setupKind": null,
      "skippedInSetup": [],
      "supportsConnectionTest": false
    }
  ],
  "connections": [],
  "imports": null,
  "kpis": {
    "attentionCount": 0,
    "connectedCount": 0,
    "coveragePct": 0,
    "lastSuccessAt": null,
    "registeredCount": 0
  },
  "orphanedDeadLetters": [],
  "projects": [
    {
      "clientName": "Hidden by selection",
      "id": "00000000-0000-4000-8000-000000000006",
      "name": "Hidden by selection"
    },
    {
      "clientName": "Synthetic visible client",
      "id": "11111111-1111-4111-8111-111111111111",
      "name": "Synthetic visible project"
    }
  ]
}

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/data-sources" \
  --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/data-sources", {
  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/data-sources", 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.

List workspace source connections

Operation: connections.list · GET /connections

List the workspace connections and their current resource/sync availability as used by onboarding. Requires integrations.manage. The list includes safe connection identity and status, never provider credentials. This is the complete configured connection list with no pagination. Creating, reconnecting, testing or revoking a connection is outside this read operation. Preserve null, unavailable and partial evidence, source provenance, confidence qualifiers and currency units; absent evidence is not zero. Dates are civil dates in the supplied IANA zone. No individual performance ranking is returned. Requires a current workspace member, this operation's exact key scope and current creator permission. Invalid filters return 400; missing or foreign resources return 404; missing permission or an effective plan restriction returns 403. Revoked or expired keys return 401; throttled requests return 429 with Retry-After.

Required key scope: data-sources:read. Current creator action: integrations.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.

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

{
  "connections": []
}

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/connections" \
  --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/connections", {
  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/connections", 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.

List filtered audit events

Operation: audit.list · GET /audit/events

Read append-only audit events with search, eventType, connector, impact, actor, status, severity and quick filters. Comma-separated or repeated values are accepted. Optional client/project bounds apply to rows, headline totals and filter options. Date filters require start/end/tz together. Limit is 1–100 (default 50); pass nextCursor as cursor for the next page. Existing audit.read and payload-retention access rules apply on Free, Entry and Growth; no Enterprise-only gate is invented. This operation does not export or replay audit data. Preserve null, unavailable and partial evidence, source provenance, confidence qualifiers and currency units; absent evidence is not zero. Dates are civil dates in the supplied IANA zone. No individual performance ranking is returned. Requires a current workspace member, this operation's exact key scope and current creator permission. Invalid filters return 400; missing or foreign resources return 404; missing permission or an effective plan restriction returns 403. Revoked or expired keys return 401; throttled requests return 429 with Retry-After.

Required key scope: audit-trail:read. Current creator action: audit.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.

  • start, end and tz travel together; start must not follow end.

  • tz must be a recognized IANA time zone; explicit historical dates remain subject to the current effective reporting window.

  • Each multi-value filter must satisfy the shared Audit Trail enum/value and list-count bounds after splitting comma-separated values.

  • A cursor must refer to an event inside the current workspace and selected client/project dataset.

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

View schema or synthetic response
JSON

[
  {
    "in": "query",
    "name": "search",
    "required": false,
    "schema": {
      "maxLength": 160,
      "type": "string"
    }
  },
  {
    "in": "query",
    "name": "eventType",
    "required": false,
    "schema": {
      "anyOf": [
        {
          "maxLength": 2048,
          "type": "string"
        },
        {
          "items": {
            "maxLength": 120,
            "type": "string"
          },
          "maxItems": 16,
          "type": "array"
        }
      ]
    }
  },
  {
    "in": "query",
    "name": "connector",
    "required": false,
    "schema": {
      "anyOf": [
        {
          "maxLength": 2048,
          "type": "string"
        },
        {
          "items": {
            "maxLength": 120,
            "type": "string"
          },
          "maxItems": 16,
          "type": "array"
        }
      ]
    }
  },
  {
    "in": "query",
    "name": "impact",
    "required": false,
    "schema": {
      "anyOf": [
        {
          "maxLength": 2048,
          "type": "string"
        },
        {
          "items": {
            "maxLength": 120,
            "type": "string"
          },
          "maxItems": 16,
          "type": "array"
        }
      ]
    }
  },
  {
    "in": "query",
    "name": "actor",
    "required": false,
    "schema": {
      "anyOf": [
        {
          "maxLength": 2048,
          "type": "string"
        },
        {
          "items": {
            "maxLength": 120,
            "type": "string"
          },
          "maxItems": 16,
          "type": "array"
        }
      ]
    }
  },
  {
    "in": "query",
    "name": "status",
    "required": false,
    "schema": {
      "anyOf": [
        {
          "maxLength": 2048,
          "type": "string"
        },
        {
          "items": {
            "maxLength": 120,
            "type": "string"
          },
          "maxItems": 16,
          "type": "array"
        }
      ]
    }
  },
  {
    "in": "query",
    "name": "severity",
    "required": false,
    "schema": {
      "anyOf": [
        {
          "maxLength": 2048,
          "type": "string"
        },
        {
          "items": {
            "maxLength": 120,
            "type": "string"
          },
          "maxItems": 16,
          "type": "array"
        }
      ]
    }
  },
  {
    "in": "query",
    "name": "quick",
    "required": false,
    "schema": {
      "anyOf": [
        {
          "maxLength": 2048,
          "type": "string"
        },
        {
          "items": {
            "maxLength": 120,
            "type": "string"
          },
          "maxItems": 16,
          "type": "array"
        }
      ]
    }
  },
  {
    "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" } }, { "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": "start", "required": false, "schema": { "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" } }, { "in": "query", "name": "end", "required": false, "schema": { "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" } }, { "in": "query", "name": "tz", "required": false, "schema": { "maxLength": 64, "minLength": 1, "type": "string" } }, { "in": "query", "name": "cursor", "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" } }, { "example": 1, "in": "query", "name": "limit", "required": false, "schema": { "maximum": 100, "minimum": 1, "type": "integer" } } ]

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

{
  "available": {
    "connectors": [
      {
        "count": 1,
        "id": "hidden_connector",
        "label": "hidden_connector"
      }
    ],
    "eventTypes": [
      {
        "count": 1,
        "id": "synthetic.hidden",
        "label": "synthetic.hidden"
      },
      {
        "count": 1,
        "id": "synthetic.visible",
        "label": "synthetic.visible"
      }
    ],
    "impacts": [
      {
        "count": 1,
        "id": "hidden impact",
        "label": "hidden impact"
      }
    ]
  },
  "events": [
    {
      "action": "synthetic.hidden",
      "actor": "hidden_connector",
      "actorKind": "connector",
      "clientId": null,
      "clientName": null,
      "connector": "hidden_connector",
      "hasPayload": false,
      "id": "00000000-0000-4000-8000-000000000007",
      "impacts": [
        {
          "label": "hidden impact"
        }
      ],
      "occurredAt": "2026-10-01T06:54:37.909Z",
      "projectId": "00000000-0000-4000-8000-000000000006",
      "projectName": "Hidden by selection",
      "severity": "info",
      "status": "success",
      "target": "project"
    },
    {
      "action": "synthetic.visible",
      "actor": "Workspace member",
      "actorKind": "user",
      "clientId": "33333333-3333-4333-8333-333333333333",
      "clientName": "Synthetic visible client",
      "connector": null,
      "hasPayload": false,
      "id": "11111111-1111-4111-8111-111111111111",
      "impacts": [],
      "occurredAt": "2026-10-01T06:54:37.907Z",
      "projectId": "11111111-1111-4111-8111-111111111111",
      "projectName": "Synthetic visible project",
      "severity": "info",
      "status": "success",
      "target": "project"
    }
  ],
  "headline": {
    "dataQualityWarnings": 0,
    "eventsToday": 2,
    "failedSyncEvents": 0,
    "lastFullSync": {
      "occurredAt": null,
      "state": "unavailable"
    },
    "recalculatedMetrics": 0
  },
  "nextCursor": null,
  "summary": {
    "changes": 0,
    "exports": 0,
    "failed": 0,
    "total": 2
  },
  "total": 2
}

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/audit/events?limit=1" \
  --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/audit/events?limit=1", {
  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/audit/events?limit=1", 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.

Inspect an accessible audit event

Operation: audit.read · GET /audit/events/:eventId

Inspect one tenant-owned audit event and its safe explanation and chain metadata. Event access and payload visibility use the same current role and retention preferences as the Audit Trail. Missing or foreign event IDs return the same 404. Frozen report replay remains privileged and no replay/export action is exposed by this GET. This is an individual resource with no pagination. Preserve null, unavailable and partial evidence, source provenance, confidence qualifiers and currency units; absent evidence is not zero. Dates are civil dates in the supplied IANA zone. No individual performance ranking is returned. Requires a current workspace member, this operation's exact key scope and current creator permission. Invalid filters return 400; missing or foreign resources return 404; missing permission or an effective plan restriction returns 403. Revoked or expired keys return 401; throttled requests return 429 with Retry-After.

Required key scope: audit-trail:read. Current creator action: audit.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.

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

View schema or synthetic response
JSON

[
  {
    "example": "11111111-1111-4111-8111-111111111111",
    "in": "path",
    "name": "eventId",
    "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

{
  "event": {
    "action": "synthetic.visible",
    "actor": "Workspace member",
    "actorKind": "user",
    "after": null,
    "before": null,
    "chain": [
      {
        "at": "2026-10-01T06:54:37.907Z",
        "connector": null,
        "detail": "Workspace member · success",
        "id": "11111111-1111-4111-8111-111111111111",
        "kind": "norm",
        "sub": "project",
        "title": "synthetic.visible"
      }
    ],
    "clientId": "33333333-3333-4333-8333-333333333333",
    "clientName": "Synthetic visible client",
    "connector": null,
    "explain": null,
    "hasPayload": false,
    "id": "11111111-1111-4111-8111-111111111111",
    "impacts": [],
    "occurredAt": "2026-10-01T06:54:37.907Z",
    "payload": {},
    "projectId": "11111111-1111-4111-8111-111111111111",
    "projectName": "Synthetic visible project",
    "related": [],
    "severity": "info",
    "status": "success",
    "target": "project"
  }
}

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/audit/events/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/audit/events/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/audit/events/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.

Read current workspace usage and billing

Operation: billing.read · GET /billing

Inspect current plan, entitlement caps, trial dates and billing ownership using the existing billing.read policy. Effective trial or downgrade state is resolved at request time. Checkout availability is informational and reflects current deployment and billing ownership; this GET does not contact Stripe or change a subscription. Amounts retain their currency and minor-unit conventions. The response is one billing summary without pagination. Preserve null, unavailable and partial evidence, source provenance, confidence qualifiers and currency units; absent evidence is not zero. Dates are civil dates in the supplied IANA zone. No individual performance ranking is returned. Requires a current workspace member, this operation's exact key scope and current creator permission. Invalid filters return 400; missing or foreign resources return 404; missing permission or an effective plan restriction returns 403. Revoked or expired keys return 401; throttled requests return 429 with Retry-After.

Required key scope: usage-billing:read. Current creator action: billing.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.

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

{
  "billing": {
    "cancelAtPeriodEnd": false,
    "catalogVersion": "v2",
    "currentPeriodEnd": null,
    "lastPaymentAt": null,
    "lastPaymentStatus": null,
    "managedPayments": false,
    "plan": "free",
    "status": "free",
    "stripeCustomerId": null,
    "stripePriceId": null,
    "stripeProductId": null,
    "stripeSubscriptionId": null,
    "trialEndsAt": null,
    "updatedAt": "1970-01-01T00:00:00.000Z",
    "workspaceId": "22222222-2222-4222-8222-222222222222"
  },
  "canManageBilling": true,
  "checkoutAvailable": false,
  "checkoutCatalogVersion": "v2",
  "checkoutPlans": [],
  "entitlements": {
    "cancelAtPeriodEnd": false,
    "caps": {
      "activeProjects": 10,
      "clients": "unlimited",
      "customRoles": false,
      "dataWindowDays": 365,
      "distributionRecipients": "unlimited",
      "includedCreditsPerPeriod": 100,
      "projects": "unlimited",
      "qaAccess": true,
      "reportsPerMonth": 100,
      "scheduledBundles": "unlimited",
      "syncFrequency": "daily"
    },
    "catalogVersion": "v2",
    "currentPeriodEnd": null,
    "effectiveCatalogVersion": "v2",
    "effectivePlan": "growth",
    "plan": "free",
    "status": "free",
    "trialEndsAt": "2026-10-15T06:54:37.897Z",
    "trialOrigin": "workspace_signup"
  },
  "productTrial": {
    "catalogVersion": "v2",
    "endsAt": "2026-10-15T06:54:37.897Z",
    "origin": "workspace_signup",
    "plan": "growth",
    "startsAt": "2026-10-01T06:54:37.897Z",
    "workspaceId": "22222222-2222-4222-8222-222222222222"
  },
  "providerManagementUrl": null
}

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/billing" \
  --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/billing", {
  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/billing", 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.

Other families: directory, authentication, clients/projects, imports, commercial inputs, assumptions, investigations, scenarios, reports.

Search documentation

Enter a word or phrase to search documentation.