Tracking Fix Lifecycle Metrics

This guide explains how to retrieve four key lifecycle tracking fields using the GET /api/rest/fix-reports/{fixReportId} endpoint. These fields support reporting on issue age, fix velocity, and remediation tracking across your security program.

Overview

All four metrics are available from a single API call:

Metric
JSON Path from Response Root
Description

Vendor / Source

fixReport[].vulnerabilityReport.vendor

The SAST scanner that identified the issue (e.g. snyk, fortify)

First Observed Date

fixReport[].fixes[].vulnerabilityReportIssues[].sharedState.createdAt

The date the issue was first detected by the scanner

Downloaded Date

fixReport[].fixes[].sharedState.downloadedBy[].downloadedAt

The date a fix was downloaded, with the user who downloaded it

Committed Date

fixReport[].fixes[].scmSubmitFixRequests[].createdAt

The date a fix was submitted as a PR or commit to source control

Step 1: Retrieve Fix Report Details (GET fix-reports/{fixReportId})

curl -X GET "https://api.mobb.ai/api/rest/fix-reports/e4cf4cd5-474a-4534-8e47-4e0761bba7c2" \
  -H "x-mobb-key: YOUR_API_KEY" \
  -H "Content-Type: application/json"

Step 2: Locate the Lifecycle Fields in the Response

The response contains all four fields within the fixes array. The example below shows two representative fixes — one in Downloaded state (no SCM submission yet) and one in Committed state (fix submitted as a PR).

Sample Response (truncated to show relevant fields):

{
    "fixReport": [
        {
            "id": "e4cf4cd5-474a-4534-8e47-4e0761bba7c2",
            "vulnerabilityReport": {
                "vendor": "snyk",
                "project": {
                    "id": "a99ee2d4-d233-4f03-a424-694bc6c74bbe",
                    "name": "marinus"
                }
            },
            "fixes": [
                {
                    "id": "a0e9ee39-029f-4b2a-a40b-24b5df6cb809",
                    "safeIssueType": "NO_LIMITS_OR_THROTTLING",
                    "safeIssueLanguage": "JavaScript",
                    "state": "Downloaded",
                    "vulnerabilityReportIssues": [
                        {
                            "id": "04236e63-41d3-4443-ba17-4a707087e5f5",
                            "vendorInstanceId": null,
                            "sharedState": {
                                "createdAt": "2025-07-07T17:21:55.010016+00:00"
                            }
                        }
                    ],
                    "scmSubmitFixRequests": [],
                    "sharedState": {
                        "isArchived": false,
                        "downloadedBy": [
                            {
                                "downloadedAt": "2026-02-26T17:32:56.523037+00:00",
                                "user": {
                                    "id": "3a33403d-6cb3-4315-b35e-da52c9dc91b6",
                                    "email": "[email protected]"
                                }
                            }
                        ],
                        "fixRatings": []
                    }
                },
                {
                    "id": "ded982cf-ad6b-4fed-b1f9-99dc8012241c",
                    "safeIssueType": "SQL_Injection",
                    "safeIssueLanguage": "JavaScript",
                    "state": "Committed",
                    "vulnerabilityReportIssues": [
                        {
                            "id": "02ce56c0-710f-49f9-b5ff-72d963cfc1d0",
                            "vendorInstanceId": null,
                            "sharedState": {
                                "createdAt": "2025-07-07T17:21:58.22535+00:00"
                            }
                        }
                    ],
                    "scmSubmitFixRequests": [
                        {
                            "prId": "51",
                            "prStatus": "ACTIVE",
                            "prUrl": "https://github.com/antonychiu2/Marinus/pull/51",
                            "submitBranchName": "Mobb-fix-e55e8e3628",
                            "commitUrl": null,
                            "createdAt": "2025-12-19T20:02:55.495498+00:00",
                            "updatedAt": "2025-12-19T20:02:55.495498+00:00"
                        }
                    ],
                    "sharedState": {
                        "isArchived": false,
                        "downloadedBy": [
                            {
                                "downloadedAt": "2026-02-26T17:32:57.03292+00:00",
                                "user": {
                                    "id": "3a33403d-6cb3-4315-b35e-da52c9dc91b6",
                                    "email": "[email protected]"
                                }
                            },
                            {
                                "downloadedAt": "2025-07-10T00:22:23.616325+00:00",
                                "user": {
                                    "id": "313292e8-7969-4538-9301-97c7b7fd16e4",
                                    "email": "[email protected]"
                                }
                            }
                        ],
                        "fixRatings": []
                    }
                }
            ]
        }
    ]
}

Field Reference

1. Vendor / Source — fixReport[].vulnerabilityReport.vendor

The SAST scanner that generated the original vulnerability report. In the example above, "vendor": "snyk" indicates the issues were sourced from Snyk. Common values include snyk, fortify, sonarqube, checkmarx, and semgrep.

2. First Observed Date — fixReport[].fixes[].vulnerabilityReportIssues[].sharedState.createdAt

The timestamp when the issue was first detected. Each entry in vulnerabilityReportIssues represents one underlying scanner issue tied to a fix. When a fix covers multiple issues, take the earliest createdAt across the array to determine the true first observed date.

In the example above, the NO_LIMITS_OR_THROTTLING fix was first observed on 2025-07-07T17:21:55.010016+00:00.

3. Committed Date — fixReport[].fixes[].scmSubmitFixRequests[].createdAt

The timestamp when a fix was submitted to source control as a PR or commit. This field is only populated when the fix state is Committed. The prUrl field in the same object links directly to the PR. If scmSubmitFixRequests is an empty array, the fix has not yet been committed.

In the example above, the SQL_Injection fix was committed on 2025-12-19T20:02:55.495498+00:00 via PR #51.

4. Downloaded Date — fixReport[].fixes[].sharedState.downloadedBy[].downloadedAt

The timestamp when a fix was downloaded, along with the user who performed the download. Multiple entries indicate the fix was downloaded by more than one user or downloaded multiple times. The downloadedAt field on each entry records the exact timestamp for each download event.

In the example above, the SQL_Injection fix was downloaded twice — first by [email protected] on 2025-07-10 and again by [email protected] on 2026-02-26.

Last updated