Beta
Get a Workflow’s Findings Summary
A summary of the workflow as a whole: its id, its computed score, its workflow-wide severity tally and its generated reports. It doesn’t include the findings themselves: see List a Workflow’s Findings for the flat list, or Get a Workflow’s Findings by Category for the categorized view.
score is computed whenever the workflow’s data allows it, whether the workflow is still in progress or complete.
Reading this summary has no side effects and is safe to poll. Following a report’s download link is different: see Reports below.
Sample
url="https://api.pointservices.com/riskinsight-services-ws/resources/v1/findings/workflows/wfpop_0000000000002082611"
curl -X GET "${url}" \
-H "Authorization: Bearer your_access_token_here"
Header Properties
| Property | Value | Required? |
|---|---|---|
| Authorization | Bearer your token | true |
Path Parameters
| Property | Description | Type |
|---|---|---|
| workflowId | The workflow’s id, exactly as this API returned it. | string |
workflowId, findingId and attachmentId are opaque. Send each one back exactly as this API returned it: don’t parse it, build one yourself, or add or remove its prefix. A findingId or attachmentId that isn’t exactly as published, including one with its prefix removed, returns a 404 as if it didn’t exist.
Responses
200
| Property | Description | Type |
|---|---|---|
| workflowId | The workflow’s id, echoed so a payload read, stored or logged on its own still says which workflow it belongs to. | string |
| score | 0 to 99, and higher is worse: the scale is inverted from what you might expect. 75 and above means there are unreviewed findings of HIGH severity. May be absent: see below. | integer |
| severityCounts | Workflow-wide tally, one entry per distinct (severity, reviewed) combination actually present. [] when nothing matched. | array |
| reports | This workflow’s generated reports. Always an array: [] when nothing has been generated yet, never null. It holds at most one entry, the workflow’s newest report. Iterate the array rather than assuming a single element. | array |
severityCounts entry
| Property | Description | Type |
|---|---|---|
| severity | The severity, as on a finding’s severity. Not a closed set. | string |
| reviewed | Whether the findings in this tally have been reviewed. | boolean |
| count | How many findings share this severity and reviewed state. | integer |
The same (severity, reviewed) pair never appears twice in one array.
Reports
| Property | Description | Type |
|---|---|---|
| name | A suggested file name for the downloaded document: the report’s own recorded name when it has one, otherwise report plus the extension its contentType implies. Treat it as a hint; the authoritative name is the Content-Disposition header the download returns. | string |
| contentType | The media type of the bytes links.download returns. Not always application/pdf: a product configured with several report types (PDF and XML, for example) can have a non-PDF report as its newest. Read this field rather than assuming PDF. | string |
| links.download | Where the report’s bytes are served from, in src. The target is the document, not JSON. An ordinary authenticated address, never a signed or expiring URL. | object |
Following reports[].links.download has side effects; reading the reports array doesn’t. Every fetch of the download records that the report was read and acknowledges the workflow’s pending report notification. On some configurations a fetch also regenerates the report when it is out of date with later edits. Which of these happen depends on the workflow’s product, not on your request. Fetch the download only when a person wants the document. Never poll it or use it to check whether a report exists: read the reports array for that.
{
"workflowId": "wfpop_0000000000002082611",
"score": 82,
"severityCounts": [
{ "severity": "HIGH", "reviewed": false, "count": 2 },
{ "severity": "MEDIUM", "reviewed": true, "count": 5 },
{ "severity": "CLEAR", "reviewed": true, "count": 11 }
],
"reports": [
{
"name": "report.pdf",
"contentType": "application/pdf",
"links": {
"download": {
"src": "https://api.pointservices.com/riskinsight-services-ws/resources/v1/findings/workflows/wfpop_0000000000002082611/reports/_latestpdf/content"
}
}
}
]
}
To download the report when a person asks for it:
url="https://api.pointservices.com/riskinsight-services-ws/resources/v1/findings/workflows/wfpop_0000000000002082611/reports/_latestpdf/content"
curl -X GET "${url}" \
-H "Authorization: Bearer your_access_token_here" \
-o report.pdf
Follow the src the summary gives you rather than building this address yourself.
score may be absent. When the workflow’s data can’t be scored right now, the key is omitted. Absence means “not computable right now”: never treat a missing score as zero, and never treat it as evidence that the workflow has no findings.
A response with no score and no report yet. severityCounts and reports are still present:
{
"workflowId": "wfpop_0000000000002082611",
"severityCounts": [],
"reports": []
}
401
No credential the service could accept reached it. The body is an RFC 9457 problem document, served as application/problem+json, and the response carries a WWW-Authenticate challenge. The request body is never read, so a 401 says nothing about whether the rest of your request would have been accepted.
Two problem types tell the cases apart:
type | Meaning | WWW-Authenticate |
|---|---|---|
about:blank | No credential was presented. | Bearer realm="Helix" |
https://pointservices.com/problems/invalid-token | A credential was presented and rejected. The response doesn’t say why: an expired, revoked, badly signed and malformed token all look the same. | Bearer realm="Helix", error="invalid_token" |
{
"type": "https://pointservices.com/problems/invalid-token",
"title": "The access token was not accepted",
"status": 401,
"detail": "The access token was rejected.",
"instance": "urn:pps:request:0000000000000000000000000000000000000000000000000000"
}
Refresh your token on a 401, and only on a 401. An expiring token moves a call from 200 to 401, never to 403, so a fresh token is the fix here and never the fix for a 403.
403
You may not read this workflow.
You are authenticated, and the answer is still no. This is an authorization decision, not a statement about your token, so refreshing the token won’t turn it into a 200.
The body is an RFC 9457 problem document, served as application/problem+json. Two problem types tell the cases apart:
type | Meaning |
|---|---|
about:blank | The request was refused before the operation ran. |
https://pointservices.com/problems/not-authorized | The operation ran, and policy won’t let you act on the workflow or finding you named. |
{
"type": "https://pointservices.com/problems/not-authorized",
"title": "Not authorized",
"status": 403,
"detail": "The authenticated identity is not permitted to perform this action.",
"instance": "urn:pps:request:0000000000000000000000000000000000000000000000000000"
}
A 403 can also come from the edge, before the service is reached: for example, when a request value resembles SQL injection or cross-site scripting. Those refusals carry no problem document. Write your client to handle an error response it can’t parse, rather than assuming every failure has a JSON body.
404
Unknown workflowId.
The body is an RFC 9457 problem document, served as application/problem+json. Two problem types tell the cases apart:
type | Meaning |
|---|---|
https://pointservices.com/problems/not-found | An id in the path isn’t one this API knows. Check that you sent it exactly as the API returned it. |
about:blank | The URL or method isn’t one this API serves at all. Check the path. |
| Property | Description | Type |
|---|---|---|
| type | An absolute URI identifying the problem type. This is the stable value to match on; compare it as a string. | string |
| title | A short summary, written for a person. | string |
| status | The HTTP status code, repeated in the body. | number |
| detail | An explanation of this occurrence, written for your logs. Never match on it. | string |
| instance | A URI identifying this occurrence, written as urn:pps:request:<id>. The id is the same value as the x-pps-request-id response header. Quote it when you report a problem to PPS. | string |
{
"type": "https://pointservices.com/problems/not-found",
"title": "No such resource",
"status": 404,
"detail": "Workflow[wfpop_0000000000002082611] not found",
"instance": "urn:pps:request:8d3a1f56-6c94-4e20-b7f8-0a5e9c2d4b73"
}
Branch on type, never on the text of title or detail.