{
    "openapi": "3.0.3",
    "info": {
        "title": "Prediction API",
        "description": "API for Grip on Software prediction results.",
        "version": "1.0.0",
        "contact": {
            "name": "Grip on Software",
            "url": "https://gros.liacs.nl"
        },
        "license": {
            "name": "Apache License, Version 2.0",
            "url": "https://www.apache.org/licenses/LICENSE-2.0.html"
        }
    },
    "servers": [
        {
            "url": "/prediction/",
            "description": "Prediction API for an individual organization's data set, a combined entry point or an organization within a combined data set.",
            "variables": {
                "organization": {
                    "enum": ["/combined/myorg", "/myorg"],
                    "default": "/combined/myorg",
                    "description": "The organization or combined path."
                }
            }
        }
    ],
    "components": {
        "parameters": {
            "BranchParam": {
                "name": "branch",
                "in": "path",
                "description": "API route and branch name of the model to use. This value must start with `v1`. If a model branch is provided, it must be prefixed with a dash (`-`). Otherwise, the default `master` branch is used.",
                "required": true,
                "schema": {
                    "type": "string",
                    "pattern": "^v1(-[-_0-9a-zA-Z]+)?$"
                }
            },
            "ProjectParam": {
                "name": "project",
                "in": "path",
                "description": "Project for which to retrieve prediction information.",
                "required": true,
                "schema": {
                    "type": "string"
                }
            },
            "SprintParam": {
                "name": "sprint",
                "in": "path",
                "description": "Sprint for which to retrieve prediction information. Can be `latest` or a valid sprint identifier of a recent sprint.",
                "required": true,
                "schema": {
                    "anyOf": [
                        {
                            "type": "string",
                            "enum": ["latest"]
                        },
                        {
                            "type": "integer",
                            "minimum": 1
                        }
                    ],
                    "default": "latest"
                }
            }
        }
    },
    "paths": {
        "/api/{branch}/predict/jira/{project}/sprint/{sprint}": {
            "get": {
                "summary": "Get sprint predictions",
                "description": "Retrieve information from the prediction model on a project's sprint.",
                "responses": {
                    "200": {
                        "description": "Sprint predictions",
                        "content": {
                            "application/json": {
                                "examples": {
                                    "P1": {"value":{"project":"Proj1","sprint":2,"id":123,"board_id":4,"name":"Sprint 2","start_date":"2019-07-07 12:34:56","end_date":"2019-07-21 21:21:21","prediction":20,"probability":null,"risk":null,"metrics":null,"analogies":[],"features":["sprint_days","num_story_points"],"tags":[],"configuration":{},"weighted":false,"stratified":false,"binary":null,"model":"abe","label":{"expression":"round(done_story_points)","attributes":["done_story_points"]},"sources":{}}},
                                    "TEST": {"value":{"project":"Test","sprint":32,"id":1243,"board_id":42,"name":"Test Sprint","start_date":"2019-06-23 12:34:56","end_date":"2019-07-07 14:32:10","prediction":40,"probability":null,"risk":null,"metrics":null,"analogies":[{"project":"Test","project_id":"TEST","sprint":27,"board_id":42,"id":1212,"name":"Earlier Sprint","start_date":"2019-05-02 10:10:10","end_date":"2019-05-16 17:44:33","label":22,"features":{"sprint_days":14,"num_story_points":44,"num_weighted_points":0.4,"num_links":33,"num_comments":44,"avg_concurrent_progress":3.145,"over_value":0,"over_expectation":-1,"number_of_devs":5,"number_of_vcs_devs":5,"number_of_jira_devs":12,"number_of_seats":4,"dev_sprint_experience":2,"num_new_developers":0,"team_spirit":1,"num_watchers":8,"avg_updaters":3,"done_story_points":40,"num_attachments":6,"num_labels":5,"num_impediments":1,"num_late_rank_changes":5,"num_not_done":2,"num_added_stories":0,"num_removed_stories":0,"num_stories":17,"num_done_stories":15,"avg_changes":8.1,"avg_change_day":2.127,"velocity":30.2,"avg_velocity":2.14,"other_done_issues":8,"avg_duration_progress":2.222,"num_commits":0,"avg_insertions":0,"avg_deletions":0,"avg_size":0,"avg_files":0,"avg_lines":0,"num_metrics":1,"num_red_metrics":0,"num_missing_metrics":0,"num_metric_target_changes":0,"num_early_rank_changes":4,"num_early_storypoint_changes":6,"num_early_changes":34},"tags":["sprint_is_closed","sprint_is_complete"]}],"features":{"sprint_days":14,"num_story_points":30,"num_weighted_points":0.5,"num_links":22,"num_comments":12,"avg_concurrent_progress":3.3333,"over_value":1,"over_expectation":-2,"number_of_devs":4,"number_of_vcs_devs":4,"number_of_jira_devs":10,"number_of_seats":4,"dev_sprint_experience":7,"num_new_developers":2,"team_spirit":0,"num_watchers":3,"avg_updaters":2.222,"done_story_points":25,"num_attachments":4,"num_labels":4,"num_impediments":4,"num_late_rank_changes":4,"num_not_done":4,"num_added_stories":4,"num_removed_stories":4,"num_stories":12,"num_done_stories":8,"avg_changes":4.128,"avg_change_day":3.1234,"velocity":25.25,"avg_velocity":1.111,"other_done_issues":4,"avg_duration_progress":4.444,"num_commits":99,"avg_insertions":12.1212,"avg_deletions":8.8888,"avg_size":123.4567,"avg_files":5.5555,"avg_lines":6.6666,"num_metrics":1,"num_red_metrics":0,"num_missing_metrics":0,"num_metric_target_changes":0,"num_early_rank_changes":44,"num_early_storypoint_changes":4,"num_early_changes":67},"tags":["sprint_is_closed","sprint_is_complete"],"configuration":{"assignments":{"number_of_devs":{"attributes":["number_of_vcs_devs","number_of_jira_devs","number_of_seats"],"expression":"number_of_devs=where(number_of_vcs_devs > 0, number_of_vcs_devs, mean(number_of_jira_devs, number_of_seats))"},"over_expectation":{"attributes":["num_story_points","done_story_points"],"expression":"over_expectation=done_story_points-num_story_points"},"over_value":{"attributes":["velocity","avg_velocity"],"expression":"over_value=velocity>avg_velocity"}},"weighted":true,"stratified":false,"features":["sprint_days","num_story_points","num_weighted_points","num_links","num_comments","avg_concurrent_progress","number_of_devs"],"binary":null,"model":"abe","label":{"expression":"round(done_story_points)","attributes":["done_story_points"]}},"sources":{"vcs":"2019-06-25 15:15:15","project":"2019-06-24 11:12:13","jira":"2017-06-25 16:24:56","metric_history":"2019-06-24 15:51:25","metric_options":"2017-06-25 15:25:35"}}},
                                    "XY": {"value":{"project":"Classify","project_id":"XY","sprint":1,"id":11,"board_id":111,"name":"Sprint #1111","start_date":"2019-07-01 11:11:07","end_date":"2019-07-15 16:17:18","prediction":1,"probability":0.8532,"risk":0.5432,"metrics":{"prediction/mean":0.2345,"loss":123.456,"global_step":1000,"average_loss":5.6789,"auc_precision_recall":0.842,"accuracy_baseline":0.6789,"accuracy":0.8888,"label/mean":0.1234,"auc":0.5555},"analogies":null,"features":{"sprint_id":11,"sprint_days":14,"sprint_weekdays":9,"sprint_is_closed":0,"sprint_is_complete":0},"tags":[],"configuration":{"model":"dnn","label":{"expression":"num_not_done_points+num_removed_points+num_added_points","attributes":["num_not_done_points","num_removed_points","num_added_points"]},"stratified":false,"weighted":false,"binary":1},"sources":{}}}
                                },
                                "schema": {
                                    "$ref": "schema/prediction-site/sprint_prediction.json#/$defs/sprint_prediction"
                                }
                            }
                        }
                    }
                }
            },
            "parameters": [
                {"$ref": "#/components/parameters/BranchParam"},
                {"$ref": "#/components/parameters/ProjectParam"},
                {"$ref": "#/components/parameters/SprintParam"}
            ]
        },
        "/api/{branch}/predict/jira/{project}/sprints": {
            "get": {
                "summary": "Get project's recent sprints",
                "description": "Retrieve a list of recent sprints of a project that have predictions.",
                "responses": {
                    "200": {
                        "description": "Project sprints",
                        "content": {
                            "application/json": {
                                "examples": {
                                    "P1": {"value":[{"name":"Sprint 1","sprint_num":1,"sprint_id":23},{"name":"Sprint 2","sprint_num":2,"sprint_id":123}]},
                                    "TEST": {"value":[]}
                                },
                                "schema": {
                                    "$ref": "schema/prediction-site/sprints.json#/$defs/sprints"
                                }
                            }
                        }
                    }
                }
            },
            "parameters": [
                {"$ref": "#/components/parameters/BranchParam"},
                {"$ref": "#/components/parameters/ProjectParam"}
            ]
        },
        "/api/{branch}/list/jira": {
            "get": {
                "summary": "Get projects",
                "description": "Retrieve a list of identifiers for projects that have predictions.",
                "responses": {
                    "200": {
                        "description": "Projects",
                        "content": {
                            "application/json": {
                                "examples": {
                                    "test": {"value":["P1","P2","TEST","XY"]}
                                },
                                "schema": {
                                    "$ref": "schema/metadata/projects.json#/$defs/projects"
                                }
                            }
                        }
                    }
                }
            },
            "parameters": [
                {"$ref": "#/components/parameters/BranchParam"}
            ]
        },
        "/api/{branch}/list/meta": {
            "get": {
                "summary": "Get projects metadata",
                "description": "Retrieve a list of metadata fields about projects that have predictions.",
                "responses": {
                    "200": {
                        "description": "Projects metadata",
                        "content": {
                            "application/json": {
                                "examples": {
                                    "test": {"value":[{"name":"P1","quality_display_name":"Proj1","recent":true},{"name":"P2","quality_display_name":"Proj2","recent":false},{"name":"TEST","quality_display_name":"Test","recent":true},{"name":"XY","quality_display_name":"Classify","recent":true}]}
                                },
                                "schema": {
                                    "$ref": "schema/metadata/projects_meta.json#/$defs/projects_meta"
                                }
                            }
                        }
                    }
                }
            },
            "parameters": [
                {"$ref": "#/components/parameters/BranchParam"}
            ]
        },
        "/api/{branch}/configuration": {
            "get": {
                "summary": "Get model configuration",
                "description": "Retrieve parameters of the prediction model of a branch.",
                "responses": {
                    "200": {
                        "description": "Configuration",
                        "content": {
                            "application/json": {
                                "examples": {
                                    "test": {"value":{"assignments":{"number_of_devs":{"attributes":["number_of_vcs_devs","number_of_jira_devs","number_of_seats"],"expression":"number_of_devs=where(number_of_vcs_devs > 0, number_of_vcs_devs, mean(number_of_jira_devs, number_of_seats))"}},"weighted":true,"stratified":false,"features":["sprint_days","num_story_points","num_weighted_points","num_links","num_comments","avg_concurrent_progress","number_of_devs"],"binary":null,"model":"abe","label":{"expression":"round(done_story_points)","attributes":["done_story_points"]},"metadata":["project_id","sprint_id"]}}
                                },
                                "schema": {
                                    "$ref": "schema/prediction-site/configuration.json#/$defs/configuration"
                                }
                            }
                        }
                    }
                }
            },
            "parameters": [
                {"$ref": "#/components/parameters/BranchParam"}
            ]
        },
        "/api/{branch}/dataset": {
            "get": {
                "summary": "Get feature data set",
                "description": "Retrieve the data set used for the training, test and validation of the prediction model. The data set is formatted as an ARFF file.",
                "responses": {
                    "200": {
                        "description": "Data set file",
                        "content": {
                            "text/plain": {
                                "examples": {
                                    "test": {"value":"@relation sprint_data\n@attribute project_id numeric\n@attribute sprint_num numeric\n@attribute sprint_days numeric\n@attribute num_story_points numeric\n@attribute done_story_points numeric\n@attribute num_weighted_points numeric\n@attribute num_links numeric\n@attribute num_comments numeric\n@attribute avg_concurrent_progress numeric\n@data\n1,1,21,10,9,8.5,4,17,4.2\n1,2,27,13,7,6.25,3,7,2.4\n3,1,16,6,4,5.5,0,12,1.1111111111111\n4,1,13,30,25,0.5,22,12,3.3333\n"}
                                }
                            }
                        }
                    }
                }
            },
            "parameters": [
                {"$ref": "#/components/parameters/BranchParam"}
            ]
        },
        "/api/{branch}/locale/descriptions": {
            "get": {
                "summary": "Get feature descriptions",
                "description": "Retrieve localization for human-readable descriptions of features used in the prediction.",
                "responses": {
                    "200": {
                        "description": "Feature descriptions",
                        "content": {
                            "application/json": {
                                "examples": {
                                    "test": {"value":{"nl":{"sprint_num":"Sprintnummer","sprint_days":"Sprintlengte","sprint_weekdays":"Weekdagen","sprint_is_closed":"Gesloten sprint","sprint_is_open":"Open sprint","sprint_is_complete":"Complete sprint","number_of_vcs_devs":"Developer teamgrootte","number_of_jira_devs":"Project teamgrootte","number_of_seats":"Teamgrootte","number_of_devs":"Aantal developers","dev_sprint_experience":"Teamervaring","num_new_developers":"Nieuwe developers","team_spirit":"Teamstemming","lines_of_code":"Aantal regels code","unittest_line_coverage":"Unittest line coverage","num_watchers":"Issue-watchers","avg_updaters":"Issue-updaters","num_story_points":"Geplande storypoints","done_story_points":"Afgeronde storypoints","over_expectation":"Toegevoegde verwachting","num_weighted_points":"Gewogen storypoints","num_attachments":"Bijlagen","num_labels":"Labels","num_impediments":"Impediments","num_late_rank_changes":"Late rangwijzigingen","num_not_done_points":"Niet afgeronde storypunten","num_late_points":"Late storypunten","num_added_points":"Toegevoegde storypunten","num_removed_points":"Weggehaalde storypunten","num_stories":"User stories","num_done_stories":"Afgeronde stories","num_links":"Issue-links","num_comments":"Commentaren","avg_changes":"Wijzigingen per issue","avg_change_day":"Middelpunt van issuewijzigingen","velocity":"Gerealiseerde velocity","velocity_three":"Gemiddelde velocity","velocity_seven":"Langdurige velocity","over_value":"Toegevoegde velocity","other_done_issues":"Afgeronde niet-story issues","avg_concurrent_progress":"Gelijktijdige stories in progress","avg_duration_progress":"Looptijd stories in progress","num_commits":"Commits","avg_insertions":"Toegevoegde regels","avg_deletions":"Verwijderde regels","avg_size":"Commitgrootte","avg_files":"Bestanden in commit","avg_lines":"Regels in commit","num_metrics":"Metrieken","num_red_metrics":"Rode metrieken","num_missing_metrics":"Metrieken met missende bronnen","num_metric_target_changes":"Veranderde metrieknormen","num_early_rank_changes":"Tijdige rangwijzigingen","num_early_storypoint_changes":"Tijdige storypointwijzigingen","num_early_changes":"Vroege issuewijzigingen","backlog_size":"Issues op sprintbacklog","backlog_ready_status":"Issues met readystatus op sprintbacklog"},"en":{"sprint_num":"Sprint number","sprint_days":"Sprint length","sprint_weekdays":"Week days","sprint_is_closed":"Closed sprint","sprint_is_open":"Open sprint","sprint_is_complete":"Complete sprint","number_of_vcs_devs":"Development team size","number_of_jira_devs":"Project team size","number_of_seats":"Team size","number_of_devs":"Number of developers","dev_sprint_experience":"Team experience","num_new_developers":"New developers","team_spirit":"Team spirit","lines_of_code":"Number of lines of code","unittest_line_coverage":"Unittest line coverage","num_watchers":"Issue watchers","avg_updaters":"Issue updaters","num_story_points":"Planned story points","done_story_points":"Done story points","over_expectation":"Added expectation","num_weighted_points":"Weighted story points","num_attachments":"Attachments","num_labels":"Labels","num_impediments":"Impediments","num_late_rank_changes":"Late rank changes","num_not_done_points":"Unfinished story points","num_late_points":"Late story points","num_added_points":"Added story points","num_removed_points":"Removed story points","num_stories":"User stories","num_done_stories":"Done stories","num_links":"Issue links","num_comments":"Comments","avg_changes":"Changes per issue","avg_change_day":"Midpoint of issue changes","velocity":"Realized velocity","velocity_three":"Average velocity","velocity_seven":"Long term velocity","over_value":"Added velocity","other_done_issues":"Done non-story issues","avg_concurrent_progress":"Concurrent stories in progress","avg_duration_progress":"Duration of stories in progress","num_commits":"Commits","avg_insertions":"Added lines","avg_deletions":"Removed lines","avg_size":"Commit size","avg_files":"Files in commit","avg_lines":"Lines in commit","num_metrics":"Metrics","num_red_metrics":"Red metrics","num_missing_metrics":"Metrics with missing sources","num_metric_target_changes":"Changed metric targets","num_early_rank_changes":"Timely rank changes","num_early_storypoint_changes":"Timely story point changes","num_early_changes":"Early issue changes","backlog_size":"Issues on sprint backlog","backlog_ready_status":"Issues with ready status on sprint backlog"}}}
                                },
                                "schema": {
                                    "$ref": "schema/metadata/locale.json#/$defs/descriptions"
                                }
                            }
                        }
                    }
                }
            },
            "parameters": [
                {"$ref": "#/components/parameters/BranchParam"}
            ]
        },
        "/api/{branch}/locale/tags": {
            "get": {
                "summary": "Get feature tags",
                "description": "Retrieve localization for human-readable tags for some of the features used in the prediction.",
                "responses": {
                    "200": {
                        "description": "Feature tags",
                        "content": {
                            "application/json": {
                                "examples": {
                                    "test": {"value":{"nl":{"sprint_is_closed":"Gesloten","sprint_is_complete":"Compleet"},"en":{"sprint_is_closed":"Closed","sprint_is_complete":"Complete"}}}
                                },
                                "schema": {
                                    "$ref": "schema/metadata/locale.json#/$defs/tags"
                                }
                            }
                        }
                    }
                }
            },
            "parameters": [
                {"$ref": "#/components/parameters/BranchParam"}
            ]
        },
        "/api/{branch}/locale/units": {
            "get": {
                "summary": "Get feature units",
                "description": "Retrieve localization for human-readable unit format templates for features used in the prediction.",
                "responses": {
                    "200": {
                        "description": "Feature units",
                        "content": {
                            "application/json": {
                                "examples": {
                                    "test": {"value":{"nl":{"sprint_num":"Sprint #%s","sprint_days":"%s dagen","sprint_is_closed":"%s gesloten sprint","sprint_is_complete":"%s complete sprint","number_of_vcs_devs":"%s developers","number_of_jira_devs":"%s projectleden","number_of_seats":"%s full-time leden","dev_sprint_experience":"%s sprints ervaring","num_new_developers":"%s nieuwe developers","team_spirit":"Stemming van %s","num_watchers":"%s issue-watchers","avg_updaters":"%s issue-updaters","num_story_points":"%s geplande punten","done_story_points":"%s afgronde storypoints","num_weighted_points":"%s gewogen storypoints","num_attachments":"%s bijlagen","num_labels":"%s labels","num_impediments":"%s impediments","num_late_rank_changes":"%s rangwijzigingen na begin van sprint","num_not_done":"%s stories die niet afgerond zijn","num_added_stories":"%s stories toegevoegd tijdens sprint","num_removed_stories":"%s stories weggehaald tijdens sprint","num_stories":"%s stories","num_done_stories":"%s afgeronde stories","num_links":"%s issue-links","num_comments":"%s commentaren bij issues","avg_changes":"gemiddeld %s wijzigingen per issue","avg_change_day":"middelpunt van issuewijzigingen op %s dagen na begin van sprint","velocity":"%s storypoints per werkdag","avg_velocity":"velocity van %s storypoints over drie sprints","other_done_issues":"%s afgeronde issues die geen story of subtask zijn","avg_concurrent_progress":"gemiddeld %s stories die gelijktijdig in progress zijn","avg_duration_progress":"gemiddeld %s dagen in progress per story","num_commits":"%s commits","avg_insertions":"gemiddeld %s toegevoegde regels per commit","avg_deletions":"gemiddeld %s verwijderde regels per commit","avg_size":"gemiddeld %s bytes per commit","avg_files":"gemiddeld %s bestanden per commit","avg_lines":"gemiddeld %s regels per commit","num_metrics":"%s metrieken","num_red_metrics":"%s metrieken die op rood staan","num_missing_metrics":"%s metrieken met missende bron","num_metric_target_changes":"%s veranderingen aan metrieknormen","num_early_rank_changes":"%s rangwijzigingen voor begin van sprint","num_early_storypoint_changes":"%s wijzigingen aan storypoints voor begin van sprint","num_early_changes":"%s overige wijzigingen aan issues voor begin van sprint"},"en":{"sprint_num":"Sprint #%s","sprint_days":"%s days","sprint_is_closed":"%s closed sprint","sprint_is_complete":"%s complete sprint","number_of_vcs_devs":"%s developers","number_of_jira_devs":"%s project members","number_of_seats":"%s fulltime members","dev_sprint_experience":"%s sprints of experience","num_new_developers":"%s new developers","team_spirit":"Spirit %s","num_watchers":"%s issue watchers","avg_updaters":"%s issue updaters","num_story_points":"%s planned points","done_story_points":"%s done story points","num_weighted_points":"%s weighted story points","num_attachments":"%s attachments","num_labels":"%s labels","num_impediments":"%s impediments","num_late_rank_changes":"%s rank changes after start of sprint","num_not_done":"%s stories that are not done","num_added_stories":"%s stories added during sprint","num_removed_stories":"%s stories removed during sprint","num_stories":"%s stories","num_done_stories":"%s done stories","num_links":"%s issue links","num_comments":"%s issue comments","avg_changes":"average of %s changes per issue","avg_change_day":"midpoint of issuechanges at %s days after start of sprint","velocity":"%s story points per working day","avg_velocity":"velocity of %s story points over three sprints","other_done_issues":"%s done issues that are not stories or subtasks","avg_concurrent_progress":"average of %s stories that are concurrently in progress","avg_duration_progress":"average of %s days in progress per story","num_commits":"%s commits","avg_insertions":"average of %s added lines per commit","avg_deletions":"average of %s removed lines per commit","avg_size":"average of %s bytes per commit","avg_files":"average of %s files per commit","avg_lines":"average of %s lines per commit","num_metrics":"%s metrics","num_red_metrics":"%s metrics that are red","num_missing_metrics":"%s metrics with missing sources","num_metric_target_changes":"%s changes to metric targets","num_early_rank_changes":"%s rank changes before start of sprint","num_early_storypoint_changes":"%s story point changes before start of sprint","num_early_changes":"%s other issue changes before start of sprint"}}}
                                },
                                "schema": {
                                    "$ref": "schema/metadata/locale.json#/$defs/units"
                                }
                            }
                        }
                    }
                }
            },
            "parameters": [
                {"$ref": "#/components/parameters/BranchParam"}
            ]
        },
        "/api/{branch}/locale/short_units": {
            "get": {
                "summary": "Get feature short units",
                "description": "Retrieve localization for human-readable shorthand unit format templates for features used in the prediction.",
                "responses": {
                    "200": {
                        "description": "Feature short units",
                        "content": {
                            "application/json": {
                                "examples": {
                                    "test": {"value":{"nl":{"sprint_days":"%s dagen","number_of_vcs_devs":"%s devs","number_of_jira_devs":"%s leden","number_of_seats":"%s fte","dev_sprint_experience":"%s sprints","unittest_line_coverage":"%s%%","velocity":"%s punten/dag","avg_velocity":"%s punten/sprint","avg_duration_progress":"%s dagen/story","num_commits":"%s","avg_insertions":"%s regels/commit","avg_deletions":"%s regels/commit","avg_size":"%s bytes/commit","avg_files":"%s bestanden/commit","avg_lines":"%s regels/commit"},"en":{"sprint_days":"%s days","number_of_vcs_devs":"%s devs","number_of_jira_devs":"%s members","number_of_seats":"%s FTE","dev_sprint_experience":"%s sprints","unittest_line_coverage":"%s%%","velocity":"%s points/day","avg_velocity":"%s points/sprint","avg_duration_progress":"%s days/story","num_commits":"%s","avg_insertions":"%s lines/commit","avg_deletions":"%s lines/commit","avg_size":"%s bytes/commit","avg_files":"%s files/commit","avg_lines":"%s lines/commit"}}}
                                },
                                "schema": {
                                    "$ref": "schema/metadata/locale.json#/$defs/short_units"
                                }
                            }
                        }
                    }
                }
            },
            "parameters": [
                {"$ref": "#/components/parameters/BranchParam"}
            ]
        },
        "/api/{branch}/locale/source": {
            "get": {
                "summary": "Get source descriptions",
                "description": "Retrieve localization for human-readable source names and icons used in the prediction.",
                "responses": {
                    "200": {
                        "description": "Source descriptions",
                        "content": {
                            "application/json": {
                                "examples": {
                                    "test": {"value":{"nl":{"project":"Projectbronnen","metric_history":"Kwaliteitsmetrieken","metric_options":"Metriekopties","quality":"Kwaliteitsrapportage","jenkins":"Jenkins","jira":"Jira","vcs":"Versiebeheer","gitlab":"GitLab","github":"GitHub","tfs":"Team Foundation Server","subversion":"Subversion"},"en":{"project":"Project sources","metric_history":"Quality metrics","metric_options":"Metric options","quality":"Quality report","jenkins":"Jenkins","jira":"Jira","vcs":"Version control","gitlab":"GitLab","github":"GitHub","tfs":"Team Foundation Server","subversion":"Subversion"},"icon":{"project":["fas","fa-sitemap"],"metric_history":["fas","fa-chart-area"],"metric_options":["fas","fa-ruler-vertical"],"quality":["fas","fa-chart-pie"],"jenkins":["fab","fa-jenkins"],"jira":["fas","fa-chalkboard"],"vcs":["fas","fa-code-branch"],"gitlab":["fab","fa-gitlab"],"github":["fab","fa-github"],"tfs":["fab","fa-windows"],"subversion":["fas","fa-code-branch"]}}}
                                },
                                "schema": {
                                    "$ref": "schema/metadata/locale.json#/$defs/sources"
                                }
                            }
                        }
                    }
                }
            },
            "parameters": [
                {"$ref": "#/components/parameters/BranchParam"}
            ]
        },
        "/api/{branch}/locale/metadata": {
            "get": {
                "summary": "Get feature metadata",
                "description": "Retrieve metadata for features used in the prediction.",
                "responses": {
                    "200": {
                        "description": "Feature metadata",
                        "content": {
                            "application/json": {
                                "examples": {
                                    "test": {"value":{"values":{"num_story_points":{"type":"fraction","denominator":4},"over_expectation":{"type":"fraction","denominator":4},"num_weighted_points":{"type":"fraction","denominator":4},"over_value":{"type":"fraction","denominator":4},"time":{"type":"duration","unit":"days","epoch":"1970-01-01 00:00:00"},"done_story_points":{"type":"fraction","denominator":4}},"measurement":{"sprint_days":{"unit":"time"},"sprint_is_open":{"unit":"meta"},"num_story_points":{"unit":"point","moment":[1,"day"],"post":"done_story_points"},"over_expectation":{"unit":"point","superset":"done_story_points"},"num_weighted_points":{"unit":"point"},"over_value":{"unit":"point","superset":"num_story_points"},"avg_concurrent_progress":{"unit":"item"},"time":{"unit":"days"},"done_story_points":{"unit":"point","superset":"velocity_one","moment":"post","pre":"num_story_points"}}}}
                                },
                                "schema": {
                                    "$ref": "schema/metadata/features.json#/$defs/features"
                                }
                            }
                        }
                    }
                }
            },
            "parameters": [
                {"$ref": "#/components/parameters/BranchParam"}
            ]
        },
        "/api/{branch}/links/{project}": {
            "get": {
                "summary": "Get project source links",
                "description": "Retrieve links to sources of prediction data for a project within the originating systems. Only project-wide sources are enumerated in the result.",
                "responses": {
                    "200": {
                        "description": "Project sources",
                        "content": {
                            "application/json": {
                                "examples": {
                                    "P1": {"value":{}},
                                    "TEST": {"value":{"jira":"https://jira.example/jira/browse/TEST","jenkins":"http://www.jenkins.example","quality":"http://quality.example/test","gitlab":"http://www.gitlab.example/test","vcs":"http://www.gitlab.example/test"}}
                                },
                                "schema": {
                                    "$ref": "schema/metadata/project_sources.json#/$defs/project_sources"
                                }
                            }
                        }
                    }
                }
            },
            "parameters": [
                {"$ref": "#/components/parameters/BranchParam"},
                {"$ref": "#/components/parameters/ProjectParam"}
            ]
        },
        "/api/{branch}/links/{project}/sprint/{sprint}": {
            "get": {
                "summary": "Get sprint source links",
                "description": "Retrieve links to sources of prediction data for a sprint within the originating systems. Where possible, sprint-specific sources are enumerated, but some may be project-wide.",
                "responses": {
                    "200": {
                        "description": "Sprint sources",
                        "content": {
                            "application/json": {
                                "examples": {
                                    "P1": {"value":{}},
                                    "TEST": {"value":{"sprint_num":{"source":"https://jira.example/jira/secure/RapidBoard.jspa?rapidView=42&projectKey=TEST&view=reporting&chart=burndownChart&sprint=1243","type":"jira"},"sprint_days":{"source":"https://jira.example/jira/secure/RapidBoard.jspa?rapidView=42&projectKey=TEST&view=reporting&chart=sprintRetrospective&sprint=1243","type":"jira"},"sprint_is_closed":{"source":"https://jira.example/jira/secure/RapidBoard.jspa?rapidView=42&projectKey=TEST&view=reporting&chart=sprintRetrospective&sprint=1243","type":"jira"},"number_of_vcs_devs":{"source":"http://www.gitlab.example/test","type":"vcs"},"number_of_jira_devs":{"source":"https://jira.example/jira/secure/RapidBoard.jspa?projectKey=TEST&rapidView=42&view=planning","type":"jira"},"team_spirit":{"source":"http://quality.example/test"},"num_watchers":{"source":"https://jira.example/jira/secure/IssueNavigator.jspa?jqlQuery=project %3D TEST and sprint %3D 1243 and watchers %3E 0&runQuery=true","type":"jira"},"num_story_points":{"source":"https://jira.example/jira/secure/RapidBoard.jspa?rapidView=42&projectKey=TEST&view=reporting&chart=burndownChart&sprint=1243","type":"jira"},"done_story_points":{"source":"https://jira.example/jira/secure/RapidBoard.jspa?rapidView=42&projectKey=TEST&view=reporting&chart=sprintRetrospective&sprint=1243","type":"jira"},"num_attachments":{"source":"https://jira.example/jira/secure/IssueNavigator.jspa?jqlQuery=project %3D TEST and sprint %3D 1243 and attachments is not empty&runQuery=true","type":"jira"},"num_labels":{"source":"https://jira.example/jira/secure/IssueNavigator.jspa?jqlQuery=project %3D TEST and sprint %3D 1243 and labels is not empty&runQuery=true","type":"jira"},"num_impediments":{"source":"https://jira.example/jira/secure/IssueNavigator.jspa?jqlQuery=project %3D TEST and sprint %3D 1243 and Flagged %3D Impediment&runQuery=true","type":"jira"},"num_not_done":{"source":"https://jira.example/jira/secure/RapidBoard.jspa?rapidView=42&projectKey=TEST&view=reporting&chart=sprintRetrospective&sprint=1243","type":"jira"},"num_added_stories":{"source":"https://jira.example/jira/secure/RapidBoard.jspa?rapidView=42&projectKey=TEST&view=reporting&chart=sprintRetrospective&sprint=1243","type":"jira"},"num_removed_stories":{"source":"https://jira.example/jira/secure/RapidBoard.jspa?rapidView=42&projectKey=TEST&view=reporting&chart=sprintRetrospective&sprint=1243","type":"jira"},"num_stories":{"source":"https://jira.example/jira/secure/RapidBoard.jspa?rapidView=42&projectKey=TEST&view=reporting&chart=sprintRetrospective&sprint=1243","type":"jira"},"num_done_stories":{"source":"https://jira.example/jira/secure/RapidBoard.jspa?rapidView=42&projectKey=TEST&view=reporting&chart=sprintRetrospective&sprint=1243","type":"jira"},"num_links":{"source":"https://jira.example/jira/secure/IssueNavigator.jspa?jqlQuery=project %3D TEST and sprint %3D 1243 and issueFunction in hasLinks()&runQuery=true","type":"jira"},"num_comments":{"source":"https://jira.example/jira/secure/IssueNavigator.jspa?jqlQuery=project %3D TEST and sprint %3D 1243 and issueFunction in hasComments()&runQuery=true","type":"jira"},"velocity":{"source":"https://jira.example/jira/secure/RapidBoard.jspa?rapidView=42&projectKey=TEST&view=reporting&chart=sprintRetrospective&sprint=1243","type":"jira"},"avg_velocity":{"source":"https://jira.example/jira/secure/RapidBoard.jspa?rapidView=42&projectKey=TEST&view=reporting&chart=sprintRetrospective&sprint=1243","type":"jira"},"other_done_issues":{"source":"https://jira.example/jira/secure/IssueNavigator.jspa?jqlQuery=project %3D TEST and sprint %3D 1243 and \"type\" NOT IN (5,7) and resolution < %222019-05-16 17:44:33%22&runQuery=true","type":"jira"},"num_metrics":{"source":"http://quality.example/test"},"num_red_metrics":{"source":"http://quality.reports.example/test"},"num_missing_metrics":{"source":"http://quality.reports.example/test"},"num_metric_target_changes":{"source":"http://quality.reports.example/test"}}}
                                },
                                "schema": {
                                    "$ref": "schema/metadata/sprint_sources.json#/$defs/sprint_sources"
                                }
                            }
                        }
                    }
                }
            },
            "parameters": [
                {"$ref": "#/components/parameters/BranchParam"},
                {"$ref": "#/components/parameters/ProjectParam"},
                {"$ref": "#/components/parameters/SprintParam"}
            ]
        },
        "/branches": {
            "get": {
                "summary": "Get all branches",
                "description": "Retrieve branches which are potentially available on this endpoint or different endpoints.",
                "responses": {
                    "200": {
                        "description": "Branches",
                        "content": {
                            "application/json": {
                                "examples": {
                                    "test": {"value":{"_class":"org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject","jobs":[{"_class":"org.jenkinsci.plugins.workflow.job.WorkflowJob","name":"master","color":"blue","lastSuccessfulBuild":{"_class":"org.jenkinsci.plugins.workflow.job.WorkflowRun","timestamp":1561591020364}},{"_class":"org.jenkinsci.plugins.workflow.job.WorkflowJob","name":"missing","color":"red","lastSuccessfulBuild":{"_class":"org.jenkinsci.plugins.workflow.job.WorkflowRun","timestamp":1450480919253}}]}}
                                },
                                "schema": {
                                    "$ref": "schema/prediction-site/branches.json#/$defs/branches"
                                }
                            }
                        }
                    }
                }
            }
        }
    },
    "security": [{}]
}
