LinkedIn's Pay For Performance (P4P) Reports API provides insights into how your P4P jobs and contract have performed. There are 2 types of reports, Job and Budget, you can call to get various information such as performance, daily spent & clicks, and lifetime budget.
Job Reports API, regardless of "By IDs" and "By Date Range", allows you or your customer to fetch daily job performance metrics by externalJobPostingId
or partnerJobCode
, if applicable, between specified dates. Performance metrics include jobPostingInfo
(which includes jobTitle
, companyDetails
, and more) as well as lifetimeJobBudgetInfo
and performance data under jobPerformanceMetrics
. "Job Reports By IDs" will require an additional list of externalJobPostingId
as a parameter, so you can only fetch metrics for specific jobs. "Job Reports By Date Range" will only require a specific date range as an input, but you will need to manage paginations to ensure no performance degrading.
Budget Reports API is mainly for you as a partner to view remaining budget balance and expiration of your LinkecIn P4P contract as well as check the total lifetime spent of it.
Reports APIs are not mandatory to implement based on you and your customers' needs. However, to ensure future capability, we will ask you to demonstrate your understanding of these reports during certification. Also, you will still need to show that you can submit sample requests to both reports during that demonstration. In this case, please note that the demo can happen with any 3rd party REST client or Curl calls as we are verifying the awareness, not the actual adoption.
Important
- Job Reports will not include data from the current UTC day and data will be retained for one year. An example of the UTC cut-over is, if you posted a job at 5 PM Pacific Time on 1/1, which is 1 AM 1/2 (tomorrow) in UTC, then the job may take up to 24 hours (1/3 in UTC) to show up in the reports.
- Charge or spent-related data like
lifetimeBudgetSpent
and jobPerformanceMetrics
will take up to 48 hours to reflect the final amounts. The amount before 48 hours from the time the charge was incurred may be an estimated value.
- If a job was
CLOSED
before any charge was incurred, then the job may not appear in reports.
- Calling the same date range multiple times within the UTC day will NOT result in displaying new job IDs in reports as they are capped to yesterday's UTC date.
API Authorization
All requests below require access tokens obtained via the OAuth2.0 Client Credentials flow. You MUST use the token from the same Child Developer Application (or clientId
) as you created the job from.
Note
- We strongly recommend to use same access token for all concurrent and consecutive calls. An access token has a lifespan of 30 mins. Only on expiry of the existing token should a new token should be generated.
Check Job Reports By IDs
Query Parameters
Field Name |
Description |
Type |
Required |
ids |
List of the unique external partner job identifiers, such as externalJobPostingId or partnerJobCode . You can query up to 10 per request. |
String[] |
Yes |
dateRange |
Date range to fetch reports. Both start and end dates are inclusive, and one should provide valid day, month, and year values. The start date must fall within a 1-year retention period of the jobs. The end date can not be later than yesterday. One can query a max of 31 days per call. If you want to query a date range that contains two different months, then you must query twice for each month. |
DateRange |
Yes |
partnerContractId |
The ID of the partner contract to fetch the job reports for. It should be provided when the partner has multiple job contracts with LinkedIn. |
Long |
No |
Sample Request
Note
- You must use the {access_token} from the same Child Developer Application that you posted the jobs from.
- This is a versioned API.
Linkedin-Version
is required to provide to specify the right version to call.
curl --location --request GET 'https://api.linkedin.com/rest/partnerJobReports?ids=List(external-job-posting-id-1,external-job-posting-id-2)&dateRange=(start:(year:2025,month:1,day:1),end:(year:2025,month:1,day:2))' \
--header 'Authorization: Bearer {access_token}' \
--header 'Linkedin-Version: 202503' \
--header 'X-RestLi-Protocol-Version: 2.0.0'
Sample Response Body
{
"results": {
"external-job-posting-id-1": {
"jobPostingInfo": {
"externalJobPostingId": "external-job-posting-id-1",
"linkedInJobPostingId": 000000000,
"jobTitle": "Software Engineer",
"companyDetails": {
"companyName": "ABC Company",
"company": "urn:li:company:000000000"
},
"companyApplyUrl": "https://test.com/apply?jobid=external-job-posting-id-1"
},
"lifetimeJobBudgetInfo": {
"lifetimeBudgetSpent": {
"amount": "26.60",
"currencyCode": "USD"
},
"lifetimeBudgetLimit": {
"currencyCode": "USD",
"amount": "399"
},
},
"jobPerformanceMetrics": [
{
"date": {
"day": 1,
"month": 1,
"year": 2025
},
"charge": {
"amount": "13.3",
"currencyCode": "USD"
},
"applyClickCount": 4,
"viewCount": 249
},
{
"date": {
"day": 2,
"month": 1,
"year": 2025
},
"charge": {
"amount": "13.3",
"currencyCode": "USD"
},
"applyClickCount": 2,
"viewCount": 220
}
]
}
},
"errors": {
"external-job-posting-id-2": {
"code": "6005",
"message": "No job posting information found for externalJobPostingId: external-job-posting-id-2.",
"status": 404
}
}
}
Check Job Reports By Date Range
Query Parameters
Field Name |
Description |
Type |
Required |
q |
Query type. Must be a fixed value "dateRange". |
String |
Yes |
dateRange |
Date range to fetch reports from and to. Both start and end dates are inclusive. One must provide valid day, month, and year values for both fields. The start date must fall within a one-year retention period, and the end date can not be later than yesterday in UTC. The maximum number of days requested can not exceed a 7-day time frame. |
DateRange |
Yes |
partnerContractId |
The ID of the partner contract to fetch the job reports for. It should be provided when the partner has multiple job contracts with LinkedIn. |
Long |
No |
Note
- We recommend not to directly use the pagination parameters. You can use default values and rely on Link Pagination Schema to fetch subsequent pages.
Field Name |
Description |
Type |
Required |
q |
Query type. Must be |
|
|
start |
The starting index of the pagination. If not provided, default value of 0 is used. |
Integer |
No |
count |
The max number of externalJobPostingIds requested. If not provided, default value of 50 is used. Maximum of 50 is allowed. |
Integer |
No |
Sample Request
Note
- You must use the {access_token} from the same Child Developer Application that you posted the jobs from.
- This is a versioned API.
Linkedin-Version
is required to provide to specify the right version to call.
curl --location --request GET 'https://api.linkedin.com/rest/partnerJobReports?q=dateRange&dateRange=(start:(year:2025,month:1,day:1),end:(year:2025,month:1,day:4))&start=10&count=2' \
--header 'Authorization: Bearer {access_token}' \
--header 'Linkedin-Version: 202503' \
--header 'X-RestLi-Protocol-Version: 2.0.0'
Sample Response Body
{
"paging": {
"start": 10,
"count": 2,
"links": [
{
"type": "application/json",
"rel": "prev",
"href": "/rest/partnerJobReports?q=dateRange&dateRange=(end:(day:2,month:1,year:2025),start:(day:1,month:1,year:2025))&start=8&count=2"
},
{
"type": "application/json",
"rel": "next",
"href": "/rest/partnerJobReports?q=dateRange&dateRange=(end:(day:3,month:1,year:2025),start:(day:2,month:1,year:2025))&start=12&count=2"
}
],
"total": 50
},
"elements": [
{
"jobPostingInfo": {
"externalJobPostingId": "external-job-posting-id-1",
"companyApplyUrl": "https://test.com/apply?jobid=external-job-posting-id-1",
"linkedInJobPostingId": 000000000,
"companyDetails": {
"company": "urn:li:company:000000000",
"companyName": "ABC Company"
},
"jobTitle": "Technician"
},
"jobPerformanceMetrics": [
{
"date": {
"month": 1,
"year": 2025,
"day": 1
},
"applyClickCount": 0,
"charge": {
"currencyCode": "USD",
"amount": "13.30"
},
"viewCount": 25
},
{
"date": {
"month": 1,
"year": 2025,
"day": 2
},
"applyClickCount": 2,
"charge": {
"currencyCode": "USD",
"amount": "13.30"
},
"viewCount": 33
}
]
},
{
"jobPostingInfo": {
"externalJobPostingId": "external-job-posting-id-2",
"companyApplyUrl": "https://test.com/apply?jobid=external-job-posting-id-2",
"linkedInJobPostingId": 000000001,
"companyDetails": {
"company": "urn:li:company:000000001",
"companyName": "DEF Company"
},
"jobTitle": "Information Technology Specialist"
},
"jobPerformanceMetrics": [
{
"date": {
"month": 1,
"year": 2025,
"day": 2
},
"applyClickCount": 2,
"charge": {
"currencyCode": "USD",
"amount": "13.30"
},
"viewCount": 29
}
]
}
]
}
Check Budget Reports
Budget Reports API allows you as our partner to fetch your lifetime budget information. Please note that information does not include the data from today in UTC.
Query Parameters
Field Name |
Description |
Type |
Required |
partnerContractId |
The ID of the partner contract to fetch the job reports for. It should be provided when the partner has multiple job contracts with LinkedIn. |
Long |
No |
Check Budget Reports Sample Request
Note
- This report is to view overall budgets at the partner level, so you must utilize the {access_token} associated with the Parent, not Child, Developer Application.
- This is a versioned API.
Linkedin-Version
is required to specify the right version to call.
curl --location --request GET 'https://api.linkedin.com/rest/partnerBudgetReports?partnerContractId={parent_or_financial_contract_id}' \
--header 'Authorization: Bearer {access_token}' \
--header 'Linkedin-Version: 202503' \
--header 'X-RestLi-Protocol-Version: 2.0.0'
Sample Response Body
{
"serviceTermStartAt": 1690502400000,
"serviceTermEndAt": 1719817200000,
"partnerBudgetDetails": [
{
"serviceTermBudgetSpent": {
"currencyCode": "EUR",
"amount": "703.24"
},
"serviceTermBudgetLimit": {
"currencyCode": "EUR",
"amount": "300000"
}
}
]
}
Reports API Schema
Job Reports API esponse Schema
Main Schema
Field Name |
Description |
Type |
Required |
start |
The start index of pagination. |
Integer |
Yes |
count |
The number of items returned. |
Integer |
Yes |
total |
The total number of elements. |
Integer |
No |
links |
Context of previous and next page. Previous page does not exist in the first page. Next page does not exist at the last page. |
Link |
No |
Field Name |
Description |
Type |
Required |
rel |
The reference to previous or next page. |
String |
Yes |
type |
The content type of the payload |
String |
Yes |
href |
The resouce to the to the previous or next page. |
String |
Yes |
PartnerJobPostingInfo Object Schema
Field Name |
Description |
Type |
Required |
externalJobPostingId |
External job posting id (also known as partnerJobCode ) provided by the poster. |
String |
No |
linkedInJobPostingId |
LinkedIn job id to uniquely identify the job in the LinkedIn eco-system. |
Long |
No |
closeAt |
Time at which the job was closed and no longer accepts any applications. Measured in epoch milliseconds (UTC). |
Long |
No |
companyDetails |
Job company details. It contains company name and LinkedIn company page url. |
CompanyDetails |
No |
companyApplyUrl |
URL to direct applicants to apply for the specified job, if applicants should be routed to an external website. |
String |
No |
jobTitle |
Title of the job provided. |
String |
No |
PartnerReportJobBudgetInfo Object Schema
Field Name |
Description |
Type |
Required |
lifetimeBudgetSpent |
Accumulated monetary charges of the job. |
MoneyAmount |
No |
lifetimeBudgetLimit |
Total budget limit of the job. |
MoneyAmount |
No |
Field Name |
Description |
Type |
Required |
date |
UTC date when charge, view count & apply click events occurred. |
Date |
No |
charge |
Charge incurred on the given day. |
MoneyAmount |
No |
viewCount |
Total count of viewers who viewed the job on the given day. |
Long |
No |
applyClickCount |
Total count of people who clicked the apply button of the job on the given day. |
Long |
No |
CompanyDetails Object Schema
Field Name |
Description |
Type |
Required |
companyName |
Name of the company. |
String |
No |
company |
Unique identifier (known as urn ) of the company in LinkedIn eco-system. |
Company Urn |
No |
Budget Reports API Response Schema
Field Name |
Description |
Type |
Required |
serviceTermStartAt |
Service term of your P4P contract(s) starting time measured in epoch milliseconds (UTC). |
Long |
No |
serviceTermEndAt |
Service term ending time measured in epoch milliseconds (UTC). |
Long |
No |
partnerBudgetDetails |
List of your budget information by currency types within the current service term range. |
Array of PartnerReportBudgetInfo |
No |
Shared API Response Schema
Three schemas below are common among LinkedIn's APIs.
PartnerReportBudgetInfo Object Schema
Field Name |
Description |
Type |
serviceTermBudgetSpent |
Accumulated monetary charge across all P4P jobs under the partner by Developer Application. The currency type is the same as in serviceTermBudgetLimit . |
MoneyAmount |
serviceTermBudgetLimit |
Total partner budget limit of the given service term. |
MoneyAmount |
MoneyAmount Object Schema
Field Name |
Description |
Type |
Required |
amount |
Amount of money. |
String |
Yes |
currencyCode |
ISO currency code of the amount. |
Currency |
Yes |
DateRange Object Schema
Field Name |
Description |
Type |
Required |
start |
Represents the inclusive (greater than or equal to) value in which to start the range. |
Date |
Yes |
end |
Represents the inclusive value in which to end the range. |
Date |
Yes |
Date Object Schema
Field Name |
Description |
Type |
Required |
day |
Day represented in integer. Valid range from 1 to 31 depending on month. |
Int |
Yes |
month |
Month represented in integer. Valid range from 1 to 12. |
Int |
Yes |
year |
Year represented in integer. |
Int |
Yes |
Reports API Error Details
Error Code |
Http Status |
Error Message |
Reason |
Resolution |
6000 |
403 |
Caller is unauthorized to access the job reporting, unable to find valid customer developer application id. |
Access Denied |
Ensure that you are using the correct customer application credentials. |
6001 |
403 |
Caller is unauthorized to access the budget reporting, unable to find valid parent developer application id. |
Access Denied |
Ensure that you are using the correct parent application credentials. |
6003 |
500 |
Failed to find partner level service term metadata. |
Internal server error |
Please reach out to support. |
6004 |
404 |
No partner level budget information found. |
Resource Not Found |
Ensure that you are using the correct partner application credentials. |
6005 |
500 |
Failed to find partner level budget information. |
Internal server error |
Please reach out to support. |
6006 |
400 |
Invalid DateRange! Date range query param should have start and end date. |
Bad Request |
Ensure that you are using the right date range parameters. Please provide start and end date as per the schema. |
6007 |
400 |
Invalid DateRange! Start and end date is required with a valid day, month & year field. |
Bad Request |
Please refer to the schema documentation and make sure all the required fields are present for the date range param. |
6008 |
400 |
Invalid DateRange! End date can not be before start date. |
Bad Request |
Ensure that you are not providing an end date that is outside the one year period. |
6009 |
400 |
Invalid DateRange! Start date can not be outside of one year retention period. |
Bad Request |
Ensure that you are not providing a start date that is outside the one year period. |
6010 |
400 |
Invalid DateRange! Today or future UTC date reporting metrics is not supported. |
Bad Request |
Ensure that you are not providing a today or future date as the start date in UTC. |
6011 |
400 |
Invalid DateRange! Start and end date should be within the range of 1 calendar month. |
Bad Request |
Ensure that you are not providing a date range that is not within 1 calendar month, e.g. Fetching 08/26/2023 to 09/05/2023 is not acceptable. You can query API with 08/26 to 08/31 or 09/01 to 09/05. |
6012 |
500 |
Failed to find job posting details for provided external job posting ids. |
Internal server error |
Please reach out to support. |
6013 |
404 |
No job posting information found for a given externalJobPostingIds: {external-job-posting-id}. |
Resource Not Found |
Please ensure you are using the same developer application/OAuth token as you posted the job. If you were, the job may have de-duped due to the similarities with other LinkedIn jobs you posted. |
6014 |
404 |
No active or revoke budget information found for the provided partner. |
Resource Not Found |
Ensure that you are using the correct partner application credentials. |
6015 |
500 |
Failed to find lifetime job spend information for a provided external job posting ids. |
Internal server error |
Please reach out to support. |
6016 |
500 |
Internal error while fetching lifetime job spend information for a provided external job posting ids. |
Internal server error |
Please reach out to support. |
6017 |
500 |
Failed to find lifetime job budget limit information for a provided external job posting ids. |
Internal server error |
Please reach out to support. |
6018 |
500 |
Failed to find daily job charges for a provided external job posting ids. |
Internal server error |
Please reach out to support. |
6019 |
500 |
Internal error while fetching analytics information for provided external job posting ids. |
Internal server error |
Please reach out to support. |
6020 |
500 |
Failed to find job performance analytics for a provided external job posting ids. |
Internal server error |
Please reach out to support. |
6021 |
400 |
Maximum supported external job posting ids per request is 10. |
Bad Request |
Ensure that you are not calling this api with more than 10 external job posting ids. |
6022 |
400 |
Provided application id is not supported for partner level budget reports. |
Bad Request |
Ensure that you are using the correct partner application credentials. |
6023 |
400 |
Invalid DateRange! Number of days between start and end date should not be more than 7 days. |
Bad Request |
Ensure that you are not providing a date range that is within the 7 day range (Start & End dates are inclusive). |
6024 |
500 |
Failed to find daily job charges for a provided partner. |
Internal server error |
Please reach out to support. |
6025 |
500 |
Failed to find daily job analytic metrics for a provided partner. |
Internal server error |
Please reach out to support. |
6026 |
500 |
Failed to find a set of external job posting ids for a provided partner. |
Internal server error |
Please reach out to support. |
6030 |
400 |
partnerContractId must be provided since the client has multiple parent contracts. |
Bad Request |
Ensure you provide partnerContractId for your multi-contract use case, so we can fetch the correct report. |