Reports ======= .. role:: raw-html(raw) :format: html .. _Quickstart: quickstart.html Jobalyzer currently supports **Pay** and **YearsOfExperience** report types. The expected input to request these reports is described in :ref:`term-definitions`. * **Pay Report**: Compensation overview containing multiple subreports: BasePay, TotalPay, Bonus, Commission, and ProfitSharing, each with detailed statistics (10/25/50/75/90 percentiles, average, standard deviation, etc). * **Years of Experience Report**: 10/25/50/75/90 base pay percentiles across a range of years of experience, for determining how pay changes over the course of a career. .. Note:: As shown in `Quickstart`_, the formal Report Names cannot be submitted to the API. Instead, the json body of the request must contain the following: .. code-block:: JSON { "requestedReports": ["yoe", "pay"] } where an exhaustive mapping is shown below: * **Pay Report** - `pay` * **Years of Experience Report** - `yoe` While not a traditional report, there is a synchronous endpoint which serves the following: * **Skill Impact**: A list of skills associated with a job title, and how those skills change pay for that job title, along with some descriptive statistics around the relative popularity of that skill. .. report-context: Reponses -------- For each report type, all of the outputs are explained, along with some hints as to whether or not those fields may be null. Request Response ~~~~~~~~~~~~~~~~ **Links** - The key that holds the links on a successful request. If there is an error, this key will not exist. * **Self** - The base of the response URLs. Not directly useful, supplied for convenience. * **PayReport** - The URL to hit to get the Pay Report. Key will not exist if "pay" was not in the "RequestedReports" list in the Request object. * **YearsExperienceReport** - The URL to hit to get the Years Experience Report. Key will not exist if "pay" was not in the "RequestedReports" list in the Request object. .. code-block:: javascript { "Links": { "Self": "https://jobalyzer.payscale.com/jobalyzer/v2/reports/", "PayReport": "https://jobalyzer.payscale.com/jobalyzer/v1/reports//pay", "YearsExperienceReport": "https://jobalyzer.payscale.com/jobalyzer/v1/reports//yoe" }, "Warnings": null, "Errors": null } **Warnings** - A list of json objects that contains warnings if any Answers keys are incorrect. Key is always present, but value is generally null. Example warning shown for reference. Requests with warnings are still run and are still charged. Warnings will be returned if "Test" is true in request. This is the best-practice way to validate that the "Answers" keys are good. * **AnswerId** - The Answer key that was submitted which does not match an accepted key. The purpose of this warning is to inform the user that the entire content of their request will not be used because part of it could not be understood - however, the requests will still go through with the properly parsed information. * **AnswerValue** - The value that was submitted in the unaccepted Answer key. * **Message** - A message related to the type of warning generated. * **Code** - If this particular warning has a code, it will be listed here. This is generally null. .. code-block:: javascript { "Links": {}, "Warnings": [ { "AnswerId": "notananswer", "AnswerValue": "test", "Message": "Submitted AnswerId 'notananswer' was not found and will not influence the reports.", "Code": null } ], "Errors": null, } **Errors** - A list of errors which caused the request to be abandoned. Key is always present, but value is generally null. * **AnswerId** - The Answer key that caused the error. If a required entry is missing, this AnswerId will be "Answers". * **AnswerValue** - The value that was submitted in the Answer key that caused the error. If a required entry is missing, the value here is null. * **Message** - A message related to the type of error generated. * **Code** - If this particular warning has a code, it will be listed here. .. code-block:: javascript { "Errors": [ { "AnswerId": "JobTitle", "AnswerValue": "Software Dev", "Message": "Not a confirmed answer", "Code": "Unconfirmed" } ] } .. _pay-report-response: Pay Report ~~~~~~~~~~ Below is the short version of the documentation for the PayReport object. Longer responses can be found in the FAQ, hyperlinked where available. The raw JSON response is broken up, alternating comments and raw response objects. **Reports** - A dictionary containing the Pay SubReports. This key may be null if an error occurred on the backend. .. code-block:: javascript { "Reports": { **BasePayReport** - the "Base Pay" Report, which describes the distribution of Base Pay. All other subreports follow an identical structure, so they have been omitted. Any subreport may be null, but the key will be present. Check :faq-topic:`What is "Base Pay" in a Base Pay Report? ` for more information. :raw-html:`
` * **CurrencyFormat** - The format of the currency. This will change based on input country. :raw-html:`
` * **CurrencyName** - The name of the currency. This will change based on input country. .. code-block:: javascript { "Reports": { "BasePayReport": { "CurrencyName": "U.S. Dollar (USD)", "CurrencyFormat": "${#}", **Count** - The number of profiles used to generate this distribution. Max of 45, but may be lower if data is sparse. See :faq-topic:`Why 45 Profiles? ` for more information. :raw-html:`
` **Percent** - The percent of selected profiles which contain this field. Some fields, like Bonus and Profitshare, are more spare, and the Percent there is generally lower. :raw-html:`
` **Percentile[10, 25, 50, 75, 90]** - The value at the 10th through 90th percentiles for this distribution. Here it is Base Pay, but the same pattern follows for other SubReports. :raw-html:`
` **Average** - The Average pay for this SubReport. This is the Mean, while Percentile50 is the Median. .. code-block:: javascript { "Reports": { "BasePayReport": { ... "Count": 45, "Percent": 100, "Percentile10": 52342.2623434234, "Percentile25": 67851.9468393747, "Percentile50": 83743.63569854344, "Percentile75": 102032.41709303796, "Percentile90": 121748.59472311698, "Average": 86667.45828009455, **Statistics** - Some statistics around the selected cohort of 45 profiles. These are interesting, but are not the best place to determine whether or not the report is good - see `ReportRating`_ field for that. :raw-html:`
` * **Count** - The same as above, the number of profiles from this cohort of up to 45 profiles which have this attribute. :raw-html:`
` * **Percent** - The same as above, the percent of selected profiles which contain the value used in this SubReport. :raw-html:`
` * **Mean** - The same as "Average" above, the average "pay" value for this SubReport. :raw-html:`
` * **StdDev** - The standard deviation of the distribution, reported in the above currency. :raw-html:`
` * **Skewness** - Describes how the data are distributed around the Median. In general, if the Average > Median, there is Positive Skew, which means the distribution has a long right tail. A value of 0 indicates a Normal Distribution. Values generally range from 0.5 to 1. See :raw-html:`Wikipedia - Skewness` for more information. :raw-html:`
` * **Kurtosis** - Describes the "tailedness" of the data. A larger value indicates that more data lie near the edges, or tails, of the distribution. See :raw-html:`Wikipedia - Kurtosis` for more information. .. code-block:: javascript { "Reports": { "BasePayReport": { ... "Statistics": { "Count": 45, "Percent": 100, "Mean": 86667.45828009455, "StdDev": 27788.248916886114, "Skewness": 0.9220428459098409, "Kurtosis": 2.7732580303759833 }, **FullPercentiles** - The "pay" value for this SubReport at each percentile, 10-90. Most points have been removed for brevity. Pay amount is in `CurrencyName` currency. .. code-block:: javascript { "Reports": { "BasePayReport": { ... "FullPercentiles": { "10": 54683.28355187092, "11": 55850.67383963341, ... "89": 119794.34231765293, "90": 121748.59472311698 } **TotalPayReport** - The SubReport whose values describe the Total Combined Compensation (TCC), or Total Pay, based on the profiles present. This SubReport has all of the entries as described above. .. code-block:: javascript { "Reports": { "TotalPayReport": {...}, **HourlyPayReport** - The SubReport whose values describe the Hourly Pay, in units of (Currency) per hour, based on the profiles present. This SubReport has all of the entries as described above. .. code-block:: javascript { "Reports": { "HourlyPayReport": {...}, **Bonus** - The SubReport whose values describe the distribution of Bonuses based on the profiles present. This SubReport has all of the entries as described above. .. code-block:: javascript { "Reports": { "Bonus": {...}, **Commission** - The SubReport whose values describe the distribution of Commission based on the profiles present. This SubReport has all of the entries as described above. This SubReport has been left null to demonstrate that the key is still present if the SubReport does not have data. .. code-block:: javascript { "Reports": { "Commission": null, **ProfitShare** - The SubReport whose values describe the distribution of ProfitShare based on the profiles present. This SubReport has all of the entries as described above. .. code-block:: javascript { "Reports": { "ProfitShare": {...}, **TotalCompanies** - The total number of companies associated with the submitted JobTitle in the location best described by LevelUsed, below. Except for rare circumstances (like sparse data, or strange geographical data distributions), the location used for this will match the rest of the SubReports. :raw-html:`
` **TotalIncumbents** - The total number of employees in our data that belong to the companies counted in TotalCompanies, regardless of the JobTitle of those employee. :raw-html:`
` **TotalProfilesAnalyzed** - The total number of profiles that made up the qualified pool of candidates for this report. In general, this is the number of profiles present that match the JobTitle nationally. :raw-html:`
` **LevelUsed** - The level at which the Companies in the above TotalCompanies and TotalIncumbents were aggregated at. This value has no bearing on any other fields in this report.It can be one of three values - "Metro", or Metropolitan Statistical Area, "State", or "Country". It can help determine if those TotalCompanies and TotalIncumbents numbers are useful. .. code-block:: javascript { "Reports": { "TotalCompanies": 49, "TotalIncumbents": 3619, "TotalProfilesAnalyzed": 51975 "LevelUsed": "State", **RankedFactors** - An ordered list containing fields and scores for the Compensable Factors that were used to select the 45 best profiles out of the TotalProfilesAnalyzed. Some of these values will be null, and are there by default, regardless of input. Others are only present if that Answer was suppled. This can give insight into the way our search algorithm works, but these values aren't useful for determining if a report is "good" or not - use ReportRating for that. .. code-block:: javascript { "Reports": { "RankedFactors": [ { "Field": "State", "Score": 52 }, { "Field": "affinity\\region", "Score": 45 }, { "Field": "affinity\\government contractor", "Score": 8 } ], .. _reportrating: **ReportRating** - A value, bounded by 0 and 1, which describes the relative quality of the data in the report. A value of 1 indicates high data quality, and a value of 0 indicates low data quality. See :ref:`report-rating` for more information. .. code-block:: javascript { "Reports": { "ReportRating": 0.27266499494851326 **Report** - For PayReport, this will always be null. Other reports (like `YearsExperienceReport`_) rely on 'Report' as the root key for data. :raw-html:`
` **Warnings** - This will generally be null, but the key will always be present. :raw-html:`
` **Errors** - This will generally be null, unless a report failed to complete due to an unseen error, in which case, the error message will be present in a list here. .. code-block:: javascript { "Report": null, "Warnings": null, "Errors": null, .. _Context: **Context** - This entry is always present. If "AutoResolveJobTitle" was set to True in the request, this entry will be populated, otherwise, it will be null. The data here allow users to understand what title was used in the case where a JobTitle was auto-resolved. See :faq-topic:`How Do I Know What My Job Title Auto-Resolved To? ` for more information. :raw-html:`
` **MatchedFactors** - This field will always be null, as it is used only by other processes. :raw-html:`
` **JobTitleRating** - Bounded by 0 and 100, this indicates the confidence of our matching algorithm in the title that was matched. 0 indicates low confidence, while 100 indicates high confidence. :raw-html:`
` **MatchedJobTitle** - The PayScale JobTitle that was matched to the SubmittedJobTitle. For more information on how this matching works, see :ref:`job-title-match`. :raw-html:`
` **SubmittedJobTitle** - The job title that was submitted in the request. .. code-block:: javascript { "Context": { "MatchedFactors": null, "JobTitleRating": 100, "MatchedJobTitle": "Software Developer", "SubmittedJobTitle": "Software Developer" } } .. _YearsExperienceReport: Years Experience Report ~~~~~~~~~~~~~~~~~~~~~~~ **Report** - A dictionary containing the YearsExperience Report entries. Please note the missing s - this key is `Report` and not `Reports`. .. code-block:: javascript { "Report": { **Currency** - A dictionary describing the currency used for this report. This will change with input country. * **Name** - The name of the currency. For United States, it is "U.S. Dollar (USD)". For Canada, it is "Canadian Dollar (CAD)". * **Id** - A number identifying the currency. This is only used internally and can be disregarded. * **Format** - A string representing how the currency should be displayed - injecting a pay value for "{#}" will yield a properly-formatted dollar amount in the currency. * **Abbreviation** - The popular abbreviation for this currency. .. code-block:: javascript { "Report": { "Currency": { "Name": "U.S. Dollar (USD)", "Id": 3079, "Format": "${#}", "Abbreviation": "USD" }, **Ranges** - A list of report objects which represent a snippet of a PayReport, binned by a certain YearsExperience range. This is generally of length 5, and the bins are auto-sized (in terms of beginning and ending YearsExperience and in total range) to capture the data that is available. The following fields are present in each Range, but have been omitted from the documentation for brevity. * **Name** - A short phrase representing the YearsExperience range of the profiles within this bucket. Generally phrased like "Less than n year(s)", "a to b years", or "n years or more". * **Percent** - The percent of selected profiles that fall within this YearsExperience bucket. These should sum to 100 across the 5 buckets. * **Average** - The average Salary (Base Pay) associated with profiles within this YearsExperience bucket. For more information on Base Pay, see :faq-topic:`What is "Base Pay" in a Base Pay Report? ` * **StdDev** - The standard deviation of the Salary (Base Pay) within this YearsExperience bucket, reported in the Currency above. * **Percent[10, 25, 50, 75, 90]** - The Salary (Base Pay) at various percentiles of the distribution within this YearsExperience bucket. .. code-block:: javascript { "Report": { "Ranges": [ { "Name": "Less than 1 year", "Percent": 18.956598430002288, "Average": 71866.5199649038, "StdDev": 20979.127136943167, "Percent10": 48612.253636725945, "Percent25": 59229.345407804321, "Percent50": 71520.302562664554, "Percent75": 85196.129326481765, "Percent90": 99602.232646369492 }, { "Name": "1 to 2 years", "Percent": 26.173473649382849, "Average": 78925.981444278776, ... }, { "Name": "3 to 4 years", "Percent": 17.38222691609181, "Average": 86581.337372343245, ... }, { "Name": "5 to 7 years", "Percent": 16.171673481826765, "Average": 94388.552688316879, ... }, { "Name": "8 years or more", "Percent": 21.316027522696292, "Average": 115484.36813353092, ... } ], **MajorShifts** - A list of automatically tuned YearsExperience thresholds which are associated with incremental 15% increases in Salary (Base Pay). * **Experience** - The number of YearsExperience associated with this MajorShift. The first is generally 1, but afterwards, they scale as the data dictates. * **Target** - The target Salary (Base Pay) associated with this threshold. When the algorithm generates these MajorShifts, it allocates profiles into bins such that the median Salary (Base Pay) within that bin is as close to the Target value as possible. It is this allocation that generates the values in the Experience field. * **Actual** - The actual Salary (Base Pay) associated with the profiles within this Experience bin. If the Target and Actual are close, then this bin is generally reliable. .. code-block:: javascript { "Report": { "MajorShifts": [ { "Experience": 1, "Target": 70873.314896228243, "Actual": 71316.295152326362 }, { "Experience": 4, "Target": 81504.312130662525, "Actual": 82399.601949297867 }, { "Experience": 8, "Target": 93729.958950261789, "Actual": 93283.014817885545 }, { "Experience": 15, "Target": 107789.45279280112, "Actual": 107252.82673042735 } ], **ReportRating** - A value, bounded by 0 and 1, which describes the relative quality of the data in the report. A value of 1 indicates high data quality, and a value of 0 indicates low data quality. See :ref:`report-rating` for more information. .. code-block:: javascript { "Report": { "ReportRating": 0.17020274898683685 }, **Warnings** - This will generally be null, but the key will always be present. :raw-html:`
` **Errors** - This will generally be null, unless a report failed to complete due to an unseen error, in which case, the error message will be present in a list here. :raw-html:`
` **Context** - For more information on Context, see `Context`_ above - it is identical for all Reports. .. code-block:: javascript { "Warnings": null, "Errors": null, "Contest": null } Skills Impact Report ~~~~~~~~~~~~~~~~~~~~ **Answers** - A Dictionary containing a set of json objects, each of which summarizes the skill associated with its key. These keys represent confirmed Skills, which may act as inputs into the :ref:`Request Object `, and which will influence the median salary by approximately the percent associated with "PayDifferentialPercentage". These Skills, and more specifically the differentials, are only accurate for this given JobTitle. Another JobTitle, no matter how similar, may have a different set of Skills and a different PayDifferential associated with each of those skills. * **ProfileCount** - The number of Profiles associated with the given JobTitle from the last 2 years which have this skill in the PayScale dataset. * **PercentReporting** - The percentage of Profiles associated with the given JobTitle from the last 2 years which report having this skill. * **MedianBasePay** - The median Salary (Base Pay) associated with having this Skill as one of the top 3 Skills in a Profile, represented in U.S. Dollars. * **PayDifferential** - The difference, in U.S. Dollars, between the MedianBasePay associated with this Skill and the Median MedianBasePay for all of the Profiles with this JobTitle. Essentially, the raw Base Pay Differential associated with this being a top-3 Skill. * **PayDifferentialPercentage** - The difference, in relative percentage, between the MedianBasePay associated with this Skill and the Median MedianBasePay for all of the Profiles with this JobTitle. Essentially, the relative Base Pay Differential associated with this being a top-3 Skill. For concerns with negative differentials, see :faq-topic:`Why Can A Skill Differential Be Negative? ` **Context** - For more information on Context, see `Context`_ above - it is identical for all Reports. It is available for this Impact Report through the querystring argument AutoResolveJobTitle. .. code-block:: javascript { "Answers": { "Executive Support": { "ProfileCount": 3549, "PercentReporting": 26.240295, "MedianBasePay": 55169.01, "PayDifferential": 7152.9688, "PayDifferentialPercentage": 14.897038 }, "Travel Planning": { "ProfileCount": 1104, "PercentReporting": 8.162662, "MedianBasePay": 53060.207, "PayDifferential": 5044.1606, "PayDifferentialPercentage": 10.5051565 }, ... "Microsoft Excel": { "ProfileCount": 127, "PercentReporting": 0.93900186, "MedianBasePay": 44622.67, "PayDifferential": -3393.3716, "PayDifferentialPercentage": -7.067162 }, "Customer Service": { "ProfileCount": 23, "PercentReporting": 0.17005545, "MedianBasePay": 43275.35, "PayDifferential": -4740.6943, "PayDifferentialPercentage": -9.873147 } }, "Context": null } Certifications Impact Report ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ **Answers** - A Dictionary containing a set of json objects, each of which summarizes the certification associated with its key. These keys represent confirmed Certifications (Certs), which may act as inputs into the :ref:`Request Object `, and which will influence the median salary by approximately the percent associated with "PayDifferentialPercentage". These Certs, and more specifically the differentials, are only accurate for this given JobTitle. Another JobTitle, no matter how similar, may have a different set of Certs and a different PayDifferential associated with each of those Certs. * **ProfileCount** - The number of Profiles associated with the given JobTitle from the last 2 years which have this Cert in the PayScale dataset. * **PercentReporting** - The percentage of Profiles associated with the given JobTitle from the last 2 years which report having this Cert. * **MedianBasePay** - The median Salary (Base Pay) associated with having this Cert as one of the Certs in a Profile, represented in U.S. Dollars. * **PayDifferential** - The difference, in U.S. Dollars, between the MedianBasePay associated with this Cert and the Median MedianBasePay for all of the Profiles with this JobTitle. Essentially, the raw Base Pay Differential associated with this Cert. * **PayDifferentialPercentage** - The difference, in relative percentage, between the MedianBasePay associated with this Cert and the Median MedianBasePay for all of the Profiles with this JobTitle. Essentially, the relative Base Pay Differential associated with having this Cert. For concerns with negative differentials, see :faq-topic:`Why Can A Skill Differential Be Negative? ` **Context** - For more information on Context, see `Context`_ above - it is identical for all Reports. It is available for this Impact Report through the querystring argument AutoResolveJobTitle. .. code-block:: javascript { "Answers": { "Certified Public Accountant (CPA)": { "ProfileCount": 615, "PercentReporting": 22.011454, "MedianBasePay": 57158.953, "PayDifferential": 5156.149, "PayDifferentialPercentage": 9.915136 }, "Enrolled Agent (EA)": { "ProfileCount": 28, "PercentReporting": 1.0021474, "MedianBasePay": 53110.973, "PayDifferential": 1108.1702, "PayDifferentialPercentage": 2.1309817 }, ... "Bookkeeping": { "ProfileCount": 158, "PercentReporting": 5.654975, "MedianBasePay": 47291.82, "PayDifferential": -4710.982, "PayDifferentialPercentage": -9.0590925 } }, "Context": null } Education Impact Report ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ **Answers** - A Dictionary containing a set of json objects, each of which summarizes the education associated with its key. These keys represent confirmed Educations, which may act as inputs into the :ref:`Request Object `, and which will influence the median salary by approximately the percent associated with "PayDifferentialPercentage". These Educations, and more specifically the differentials, are only accurate for this given JobTitle. Another JobTitle, no matter how similar, may have a different set of Educations and a different PayDifferential associated with each of those Educations. * **ProfileCount** - The number of Profiles associated with the given JobTitle from the last 2 years which have this Education in the PayScale dataset. * **PercentReporting** - The percentage of Profiles associated with the given JobTitle from the last 2 years which report having this Education. * **MedianBasePay** - The median Salary (Base Pay) associated with having this Education as one of the Educations in a Profile, represented in U.S. Dollars. * **PayDifferential** - The difference, in U.S. Dollars, between the MedianBasePay associated with this Education and the Median MedianBasePay for all of the Profiles with this JobTitle. Essentially, the raw Base Pay Differential associated with this Education. * **PayDifferentialPercentage** - The difference, in relative percentage, between the MedianBasePay associated with this Education and the Median MedianBasePay for all of the Profiles with this JobTitle. Essentially, the relative Base Pay Differential associated with having this Education. For concerns with negative differentials, see :faq-topic:`Why Can A Skill Differential Be Negative? ` **Context** - For more information on Context, see `Context`_ above - it is identical for all Reports. It is available for this Impact Report through the querystring argument AutoResolveJobTitle. .. code-block:: javascript { "Answers": { "Doctorate (PhD)": { "ProfileCount": 152, "PercentReporting": 1.0367641, "MedianBasePay": 96608.11, "PayDifferential": 10114.368, "PayDifferentialPercentage": 11.693758 }, "Master's Degree (non-MBA)": { "ProfileCount": 3131, "PercentReporting": 21.355978, "MedianBasePay": 91319.8, "PayDifferential": 4826.056, "PayDifferentialPercentage": 5.5796595 }, ... "Bachelor's Degree": { "ProfileCount": 10340, "PercentReporting": 70.52725, "MedianBasePay": 86007.74, "PayDifferential": -485.9942, "PayDifferentialPercentage": -0.5618837 } }, "Context": null }