Symptom
This article describes how you can edit Job Application data via ODATA API.
"Image/data in this KBA is from SAP internal systems, sample data, or demo systems. Any resemblance to real data is purely coincidental."
Environment
SAP SuccessFactors Recruiting Management
Resolution
API WARNING: API upserts is a powerful tool to help you automate manual tasks and edit data that is not possible or difficult to do in the UI. However, this can also lead to unintentional data changes if mishandled. Make sure you understand how to use the ODATA API Data Dictionary and the integration tools in general. If possible, test first with your preview environment and with only a subset of your data to see whether you are getting the intended results.
Moreover, creating scripts is like creating your system's configuration, they are outside support scope (and are typically requests for partners) but if you have issues that are possible defects, please feel free to reach out to Support.
The payload presented here can be used to update any of the fields in the Application as long as they are set as updatable and upsertable = true in the data dictionary.
1. Payload Format (Example 1) - Updating the firstName and the lastName in the Application.
POST: https://apisalesdemo4.successfactors.com/odata/v2/upsert
{
"__metadata": {
"uri": "JobApplication",
"type": "SFOData.JobApplication"
},
"candidateId": "323772",
"applicationId": "514063",
"jobReqId": "1345",
"firstName": "Joe",
"lastName": "Bloggs"
}
Request Breakdown
a. The main entity JobApplication is defined as follows:
"__metadata": {
"uri": "JobApplication",
"type": "SFOData.JobApplication"
}
b. The properties (or fields) you want to edit are defined as follows:
Format: "property name as seen in the data dictionary": "value"
Example: "candidateId": "323772"
c. The sequence of the properties in the payload is not important, the system will read them as one payload. Hence, the payload above is the same as the payload below.
{
"firstName": "Joe",
"lastName": "Bloggs",
"candidateId": "323772",
"applicationId": "514063",
"jobReqId": "1345",
"__metadata": {
"uri": "JobApplication",
"type": "SFOData.JobApplication"
}
}
d. The letter case for the entities and the properties is important. They should be consistent to the entries and properties defined in the ODATA API Data Dictionary. For example, firstName cannot be firstname.
e. The Request has to be POST and the URL to use should be defined as follows:
Format: URL (according to KBA 2215682)/odata/v2/upsert
Example: https://apisalesdemo4.successfactors.com/odata/v2/upsert
f. In the request above, we are updating the first name and last name for application ID 514063 with candidate ID 323772 on requisition 1345.
"candidateId": "323772",
"applicationId": "514063",
"jobReqId": "1345",
"firstName": "Joe",
"lastName": "Bloggs"
g. As a rule of thumb, you just need the application ID (which is the unique identifier) and the fields you want to change in the request, in this case the first name and last name. So, we can essentially trim the request to just the following:
{
"__metadata": {
"uri": "JobApplication",
"type": "SFOData.JobApplication"
},
"applicationId": "514063",
"firstName": "Joe",
"lastName": "Bloggs"
}
2. Payload Format (Example 2) - Updating the firstName and the lastName in the Application.
POST: https://apisalesdemo4.successfactors.com/odata/v2/upsert
{
"__metadata":{
"uri":"https://apisalesdemo4.successfactors.com/odata/v2/JobApplication(514063L)",
"type":"SFOData.JobApplication"
},
"firstName": "Joe",
"lastName": "Bloggs"
}
Request Breakdown
a. This request is the same as Example 1, but instead of calling the application ID as a separate property, it is encapsulated in the uri of the JobApplication entity.
b. The main entity JobApplication is defined as follows:
"__metadata": {
"uri":"https://apisalesdemo4.successfactors.com/odata/v2/JobApplication(514063L)",
"type": "SFOData.JobApplication"
}
c. The URI is essentially your URL but instead of ending in /upsert it is /JobApplication(applicationID + L).
3. Payload Format (Example 3) - Updating the firstName and the lastName in the Application.
POST: https://apisalesdemo4.successfactors.com/odata/v2/upsert
{
"firstName": "Joe",
"lastName": "Bloggs",
"__metadata": {
"type": "SFOData.JobApplication",
"uri": "JobApplication(applicationId=514063)"
}}
Request Breakdown
a. This is the same request as the other examples, but instead of calling the application ID as a separate property, it is encapsulated in the uri of the JobApplication entity.
b. The main entity JobApplication is defined as follows:
"__metadata": {
"uri": "JobApplication(applicationId=514063)"
"type": "SFOData.JobApplication",
}
c. The URI is "JobApplication(applicationId=value)"
4. The examples we have are for the first name and last name, but these are applicable to other fields under the JobApplication entity as long as they are updatable and upsertable.
5. Moreover, ODATA does not acknowledge multi-stage configuration.
For example, the Conviction Details field is defined as not required in the application template.
Application Template:
<field-definition id="conviction_details" type="textarea" required="false" custom="true" public="false" readOnly="false" anonymize="false" forward-intact="false" sensitive="false">
<field-label mime-type="text-html"><![CDATA[Conviction Details]]></field-label>
</field-definition>
Then, you have multi-stage setup in the Job Requisition Template, with the conviction_details (Conviction Details) field marked as required when the Candidate [C] enters the Background status.
Job Requisition Template:
<field-permission type="write">
<description><![CDATA[C can write in these stages]]></description>
<role-name><![CDATA[C]]></role-name>
<status><![CDATA[Background]]></status>
<field application-field-id="conviction_details" required="true"/>
</field-permission>
6. This means, in the UI, the candidates will only see the Conviction Details field when they reached the Background status and by then it will be required. In addition, Recruiting users will not be able to move the applicant pass the Background status if the Conviction Details field is empty or null.
7. However, in the API, you can still do an upsert for the JobApplication successfully even without adding conviction_details in the payload because is not considered as a required field for the JobApplication entity.
REQUEST
{
"__metadata":{
"type":"SFOData.JobApplication",
"uri":"JobApplication(applicationId=97)"
},
"firstName":"Test",
"lastName":"User"
}
RESPONSE
<d:key>JobApplication/applicationId=97</d:key>
<d:status>OK</d:status>
<d:editStatus>UPDATED</d:editStatus>
<d:message>Application has been updated successfully</d:message>
8. On the other hand, you have the exact opposite setting, where the Conviction Details field is defined as required in the application template but will only appear when Candidate is under the Background status.
Application Template:
<field-definition id="conviction_details" type="textarea" required="true" custom="true" public="false" readOnly="false" anonymize="false" forward-intact="false" sensitive="false">
<field-label mime-type="text-html"><![CDATA[Conviction Details]]></field-label>
</field-definition>
With multi-stage setup in the Job Requisition Template, the conviction_details (Conviction Details) field although required, will only appear to the Candidates [C] when they enter the Background status.
Job Requisition Template:
<field-permission type="write">
<description><![CDATA[C can write in these stages]]></description>
<role-name><![CDATA[C]]></role-name>
<status><![CDATA[Background]]></status>
<field application-field-id="conviction_details" />
</field-permission>
9. This means, in the UI, the candidates will be able to initially apply without populating the conviction_details (Conviction Details) field, as it is not visible to them although, by definition, it is a required field. Only when they are moved to the Background status, then the field will be visible to them, and it will be required.
10. However, in the API, you cannot perform an upsert for the JobApplication successfully without adding conviction_details in the payload because it is considered as a required field for the JobApplication entity.
REQUEST
{
"__metadata":{
"type":"SFOData.JobApplication",
"uri":"JobApplication(applicationId=97)"
},
"firstName":"Test",
"lastName":"User"
}
RESPONSE
<d:key m:null="true"></d:key>
<d:status>ERROR</d:status>
<d:editStatus m:null="true"></d:editStatus>
<d:message>conviction_details required for external candidate as per field override, for templateId 7 , with the index 0</d:message>
11. In this case, you either have to populate the Conviction Details in the UI before the upsert or add the conviction_details field in the payload.
See Also
2885326 - How to use Postman on performing ODATA API Requests - Recruiting Management
2817669 - ODATA API Data Dictionary - Recruiting Management
2215682 - Successfactors API URLs for different Data Centers
Keywords
ODATA, API, JobApplication, Upsert, Insert, Recruiting Management, RCM, Integration , KBA , LOD-SF-RCM-API , Webservices & APIs , How To