Creating and submitting an EOR employment
This guide will show you how to create a draft employment, update the job details, and submit the employment to kick off the employment onboarding and contract generation.
Note for Reseller partners using the API - you will need to use the X-Oyster-Customer-Id
header for all of the calls in this guide. For more information, see the Reseller guide to using the Oyster API.
1. Create Employment
First you need to create an employment record, which represents the start of the hiring process for an engagement. In your request, you will need to include the employment’s ISO-3166 Alpha country code, full legal name, email, and nationality.
Example Request
curl --request POST \
--url https://api.oysterhr.com/v0.1/hiring/employments/ \
--header 'accept: application/json' \
--header 'authorization: Bearer BEARER_TOKEN_GOES_HERE' \
--header 'content-type: application/json' \
--data '
{
"personalDetails": {
"fullLegalName": "Test Hire",
"email": "[email protected]",
"nationality": "US"
},
"countryCode": "US",
"subdivisionCode": "CA"
}
'
Response
If successful, the API will return a 201 Created
response with the newly created employment details, including an id
that you will need for future updates and submission. The employment will then be in a draft
phase and ready to continue filling the contractual details.
Example Response
{
"data": {
"engagementId": "urY7zKOm",
"countryCode": "US",
"subdivisionCode": "CA",
"personalDetails": {
"fullLegalName": "Test Hire",
"email": "[email protected]",
"nationality": "US",
"workPermit": null
},
"manager": {
"managerRole": null,
"managerName": null,
"managerEmailAddress": null,
"managerPhoneNumber": null,
"managerIsExpenseApprover": false
},
"role": {
"newHireStatus": "new_hire",
"seniorityLevel": null,
"roleTypeId": null,
"role": null,
"jobDescription": null,
"startDate": null,
"endDate": null,
"employmentType": null,
"probationPeriod": null,
"terminationNotice": null,
"resignationNotice": null
},
"compensation": {
"commissionPlanOffered": null,
"commissionPlan": null,
"salary": {
"decimal": "",
"currencyCode": "USD"
},
"paidHolidayDays": null,
"bonuses": [],
"allowances": [],
"reimbursementBudgets": [],
"remoteWorkCosts": null,
"privateNotes": null,
"sickPay": null
},
"documents": [],
"defaultSigner": null
}
}
2. Update Employment
Once you’ve created the employment, you will need to update the employment with details related to the job position. In the request body, only include the fields you want to update (e.g., job_title
, annual_salary
, etc.).
Example Request
curl --request PATCH \
--url https://api.oysterhr.com/v0.1/hiring/employments/urY7zKOm \
--header 'accept: application/json' \
--header 'authorization: Bearer BEARER_TOKEN_GOES_HERE' \
--header 'content-type: application/json' \
--data '
{
"role": {
"role": "Senior Software Engineer"
},
"compensation": {
"salary": {
"decimal": "95000",
"currencyCode": "USD"
},
}
}
'
To successfully submit an Employment in the next step, most fields are required based on the Employment's designated country.
Fields | Required | Notes |
---|---|---|
seniority_level | Yes | |
role_type | Yes | This can be looked up using the Role Types endpoint |
role | Yes | The job title of the employee |
job_description | Yes | |
start_date | Yes | |
end_date | Yes | |
employment_type | Yes | This must be either FULL_TIME or PART_TIME |
working_hours | Yes | |
probation_period | Yes | |
salary | Yes | |
resignation_notice | Yes | This field is required in: Australia, UK, Ireland, India |
termination_notice | Yes | This field is required in: Australia, UK, Ireland, India |
remote_work_costs | Yes | |
vacation | Yes | |
sick_pay | Yes | This field is required in: UK, Ireland, Netherlands |
default_signer | Yes |
Response
A successful update returns the modified employment details. The status
will still be draft
until the employment is submitted in the following step.
Example Response
{
"data": {
"engagementId": "urY7zKOm",
"countryCode": "US",
"subdivisionCode": "CA",
"personalDetails": {
"fullLegalName": "Test Hire",
"email": "[email protected]",
"nationality": "US",
"workPermit": null
},
"manager": {
"managerRole": null,
"managerName": null,
"managerEmailAddress": null,
"managerPhoneNumber": null,
"managerIsExpenseApprover": false
},
"role": {
"newHireStatus": "new_hire",
"seniorityLevel": "SENIOR",
"roleTypeId": null,
"role": "Senior Software Engineer",
"jobDescription": null,
"startDate": null,
"endDate": null,
"employmentType": null,
"probationPeriod": null,
"terminationNotice": null,
"resignationNotice": null,
"fullTimeHoursPerWeek": null
},
"compensation": {
"commissionPlanOffered": null,
"commissionPlan": null,
"salary": {
"decimal": "95000",
"currencyCode": "USD"
},
"paidHolidayDays": null,
"bonuses": [],
"allowances": [],
"reimbursementBudgets": [],
"remoteWorkCosts": null,
"privateNotes": null,
"sickPay": null
},
"documents": [],
"defaultSigner": null
}
}
Optional steps
Depending on the desired contract conditions, the following optional endpoints can be used:
- Upload Employment Work Permit - used if the employment requires a work permit for the employment country. This can be deleted using the Delete the uploaded employment work permit endpoint.
- Upload Employment Commission Plan - This API endpoint allows you to upload a custom commission plan for the employment. This can be deleted using the Delete The Uploaded Employment Commission Plan endpoint.
- Upload Employment Document - This API endpoint allows you to upload any additional documents for the employment. This can be deleted using the Delete The Uploaded Employment Document endpoint.
3. Submit Employment
Once all the necessary information is submitted, you can submit the employment for processing. This marks the employment as In Progress
, at which point the employment onboarding can take place before the contracts are sent out for signature.
Example Request
curl --request POST \
--url https://api.oysterhr.com/v0.1/hiring/employments/urY7zKOm/submit \
--header 'accept: application/json' \
--header 'authorization: Bearer BEARER_TOKEN_GOES_HERE'
Response
If successful, you will receive a 200 response with the employment information.
Example Response
{
"data": {
"engagementId": "urY7zKOm",
"countryCode": "US",
"subdivisionCode": "CA",
"personalDetails": {
"fullLegalName": "Test Hire",
"email": "[email protected]",
"nationality": "US",
"workPermit": null
},
"manager": {
"managerRole": null,
"managerName": null,
"managerEmailAddress": null,
"managerPhoneNumber": null,
"managerIsExpenseApprover": false
},
"role": {
"newHireStatus": "new_hire",
"seniorityLevel": "SENIOR",
"roleTypeId": 05,
"role": "Senior Software Engineer",
"jobDescription": "job description",
"startDate": "2024-10-14",
"endDate": null,
"employmentType": "FULL_TIME",
"probationPeriod": {
"value": 12,
"unit": "MONTHS"
},
"terminationNotice": null,
"resignationNotice": null,
"fullTimeHoursPerWeek": 40
},
"compensation": {
"commissionPlanOffered": null,
"commissionPlan": null,
"salary": {
"decimal": "95000",
"currencyCode": "USD"
},
"paidHolidayDays": 14,
"bonuses": [],
"allowances": [],
"reimbursementBudgets": [],
"remoteWorkCosts": {
"allowancePolicy": {
"allowancePolicy": "MONTHLY_ALLOWANCE",
"amount": null,
"statutoryAmount": null
},
"equipmentBudget": null,
"equipmentListOwnedByTeamMember": null,
"equipmentListProvidedByCustomer": {
"equipmentList": [
"KEYBOARD",
"MOUSE",
"PRINTER"
],
"equipmentOther": null
},
"equipmentOneTimePayment": null
},
"privateNotes": null,
"sickPay": null
},
"documents": [],
"defaultSigner": {
"fullName": "Graham Vandervort",
"email": "[email protected]",
"jobTitle": "Engineering Manager",
"phone": {
"countryCode": "US",
"number": "555 654 5568"
}
}
}
}
Notes:
- Hires submitted via API will have statutory Benefits applied.
- We have an upcoming Benefits API that will allow you to set non-statutory benefits. In the meantime if you want to apply non-statutory benefits for an employment, please get in touch with Oyster.
- In countries that require values for Termination Notice, Resignation Notice and Sick Pay, statutory values will be applied.
- Applying non-statutory values for these fields will be added in a future API update. In the meantime if you want to apply non-statutory values for any of these fields, please get in touch with Oyster.
Conclusion
Once you have successfully submitted an employment and it is in the In Progress
state, the employment onboarding can begin. That can either be achieved via the platform by sending the team member an invitation or via API by following the Completing EOR employment onboarding via API guide.
Updated 8 days ago