Create An ATS Specific Contract
Integration Toolkit > Create An ATS Specific Contract
This section guides you on how to develop the Oneflow contract creation backend logic within the Oneflow Integration in your ATS system. To develop the backend logic for Oneflow contract creation within your ATS system, you should allow users to generate contracts from objects such as Candidate Profiles, Job Applications, or Offers. Contracts can be created through automated triggers (e.g., when an offer is made) or manually by selecting a specific candidate or application. The contract details, including the participants, will be populated dynamically based on the ATS object data.
After authenticating your application with Oneflow, you can decide which event in the ATS will initiate the integration (e.g., job offer accepted, candidate signed contract), and what specific data need to be transferred from ATS to Oneflow.
Oneflow Contract Stages
Below are the primary Oneflow contract stages, which can be mapped to the corresponding candidate stages in your ATS.
- Contract Created: The employment contract has been created.
- Contract Sent: The employment contract has been sent to the candidate.
- Contract Signed: All parties have signed the employment contract.
- Contract Declined: The candidate has declined the employment contract.
- Contract Overdue: The candidate has not signed the contract within the specified time frame.
- Data Field Update: When a data field in the contract is updated in Oneflow, an event is triggered to ensure these changes are reflected in your ATS. For the contract owners, this process ensures that any updates to contract details (such as job title, salary, or start date) are accurately and promptly communicated to the ATS. This can also reduce data inconsistency between your ATS and the applicant/employee’s contract in Oneflow, thus, boosting your productivity.
Below is a sample stage mapping of Oneflow contract stages to ATS stages. You can refer to this when creating your own stage mapping configuration for your ATS integration.
Stage Mapping
ATS Candidate Stage | Oneflow Contract Stage | Descrption |
---|---|---|
Offered | Contract Created and Contract Sent | When a candidate is moved to the “Offered” stage, the contract will be created and sent. |
Hired | Contract Signed | When the candidate signs the contract in Oneflow, update the ATS to move the candidate to the "Hired" stage. |
Rejected | Contract Declined | If the candidate/employer declines the contract, notify the ATS to update the status to "Rejected." |
Employer action (Offered or Rejected) | Contract Overdue | If the contract is overdue, the employer should then decide whether to extend the signing deadline or decline the contract, and take appropriate action. |
Offered | Data field update | When candidate details are changed, the changed data will be reflected in the contract. (Only possible in draft mode). |
Data Transfer
The data transfer between Oneflow and the ATS is a critical component of the integration process. This involves syncing candidate details and contract information to ensure that both systems are up-to-date and consistent.
Data transfer occurs in two main directions:
- From your ATS to Oneflow, where candidate information is used to create and update contracts,
- From Oneflow to the ATS, where contract status changes are reflected in the candidate's profile in your ATS.
This bidirectional data flow ensures seamless communication and accurate record-keeping across both platforms.
Syncing Data from ATS to Oneflow
When the integration process starts in your ATS, and the candidate moves to the "Offered" stage, the following steps can be taken to synchronize data and create the contract in Oneflow
- Candidate Moves to Offered Stage
- The ATS detects when the candidate transitions to the "Offered" stage.
- A trigger is initiated to start the data transfer process from the ATS to Oneflow.
- Fetch Latest Candidate Details
- Oneflow sends a request to the ATS to fetch the latest candidate details, including name, contact information, job position, email, and any other relevant data.
- The ATS responds with the requested candidate details.
- Create Contract in Oneflow
- Scenario 1: If the ATS provides an iframe, the user can open the Oneflow contract creation interface within the iframe, select the workspace and template, and manually create the contract.
- Scenario 2: If the ATS does not provide an iframe, Oneflow will rely on event notifications when the candidate moves to the "Offered" stage. Using these notifications, Oneflow will automatically create the contract using the Public API.
- Send the Contract
- Once the contract is created and the candidate is added as a participant, Oneflow sends the contract to the candidate for review and signature.
- Contract Signed or Declined
- Contract Signed: When the candidate and the contract owner sign the contract in Oneflow, an update will be sent to the ATS to move the candidate from the "Offered" stage to the "Hired" stage. Additionally, if the ATS allows, the signed contract will be uploaded to the ATS.
- Contract Declined: If the candidate or contract owner declines the contract in Oneflow, the ATS will update the candidate’s status from the "Offered" stage to the "Rejected" stage. Additionally, if the ATS allows, the declined contract will be uploaded to the ATS.

Create a Contract
To create a contract in Oneflow, you will need to specify the Oneflow workspace and template where the contract will be stored. To simplify this process, provide a list of available workspaces and templates for users to choose from.
Note:
Please note that new workspaces and templates can only be created within the Oneflow application.
Refer to Get workspace from Oneflow and Get templates from Oneflow for instructions on retrieving workspaces and templates.
FUNCTION CreateContract
INPUT: A request body containing:
- TriggeredBy: The user who triggered the contract creation
- Auth: Authorization details for OneFlow
- Contract details
- SendContract: Flag indicating if the contract should be sent automatically (true/false)
- ContractSubject: Subject for the contract (if SendContract is true)
- ContractMessage: Message for the contract (if SendContract is true)
OUTPUT: The ID of the created contract
BEGIN
# Step 1: Extract required data from request body
Retrieve the email of the user from TriggeredBy
Retrieve the authorization token from Auth
SET template_id TO value of 'template_id' in body
SET workspace_id TO value of 'workspace_id' in body
SET participants TO value of 'participants' in body
SET contract_name TO value of 'candidate_name' in body
SET send_contract TO value of 'SendContract' in body
SET contract_subject TO value of 'ContractSubject' in body
SET contract_message TO value of 'ContractMessage' in body
# Step 2: Prepare participant details
Call AddParticipants to add participants to the contract
# Step 3: Determine if the contract should be sent directly
IF send_contract IS TRUE THEN
IF contract_subject IS EMPTY OR contract_message IS EMPTY THEN
RETURN {'error': 'Contract subject and message cannot be empty'}
# Step 4: Create the Oneflow contract
TRY
# Calls the CreateOneflowContract function to create a contract.
SET oneflow_contract TO CALL CreateOneflowContract USING template_id, workspace_id, my_party, counterparties, and contract_name
CATCH Exception
# Handles exceptions encountered during contract creation.
HANDLE exception
END TRY
# Step 5: Return the contract ID
Return the ID of the created contract
END
If you want to include additional participants from your company in the contract, you can add them as my_party
participants. For example, you might include a line manager, supervisor, or HR manager. However, the candidate will be added as an individual party.
FUNCTION AddParticipants
INPUT: participants (contains participant details, including candidate and my_party participants)
OUTPUT: my_party (an object containing participants), parties (a list of party objects)
BEGIN
# Step 1: Initialize my_party object
Initialize an empty object called my_party
Initialize an empty list called my_party.participants
# Step 2: Add additional my_party participants (if any)
IF participants IS NOT EMPTY THEN
TRY
FOR EACH participant IN participants DO
SET participant_details TO {
'_permissions': { 'contract:update': participant_type != 'viewer' },
'name': participant.fullname,
'title': participant.jobtitle OR '',
'email': participant.email,
'phone_number': participant.phone_number,
'signatory': participant_type == 'signatory', # Set signatory as boolean
'sign_method': participant.preferred_sign_method OR 'standard_esign', # Default value
'delivery_channel': participant.preferred_delivery_channel OR 'email' # Default value
}
# Add participant details to the my_party.participants array
ADD participant_details TO my_party.participants
CATCH Exception
# Handles exceptions encountered during my_party creation
HANDLE exception
END TRY
END IF
# Step 3: Initialize parties list
Initialize an empty list called parties
# Step 4: Add the candidate as an individual counterparty
TRY
SET candidate TO {
'_permissions': { 'contract:update': false },
'name': candidate.fullname,
'title': candidate.jobtitle OR '',
'email': candidate.email,
'phone_number': candidate.phone_number,
'signatory': participant_type == 'signatory', # Set signatory as boolean
'sign_method': candidate.preferred_sign_method OR 'standard_esign', # Default value
'delivery_channel': candidate.preferred_delivery_channel OR 'email' # Default value
}
# Add candidate details to the parties list with type set to IndividualCounterparty
ADD candidate TO parties WITH type 'IndividualCounterparty'
CATCH Exception
# Handles exceptions encountered during parties creation
HANDLE exception
END TRY
# Step 5: Return the my_party object and parties list separately
RETURN my_party, parties
END
Function to create Oneflow contract
FUNCTION CreateOneflowContract(template_id, workspace_id, my_party, counterparties, contract_name)
# Purpose: Create a contract in Oneflow using the provided details.
# Step 1: Prepare the request body
CREATE body AS a key-value store WITH:
"template_id": template_id,
"workspace_id": workspace_id,
"contract_name": candidate_name,
"my_party": my_party
"parties": counterparties
# Step 2: Set up the headers for the API request
DEFINE HEADERS
SET "x-oneflow-api-token" IN HEADERS TO user.apiToken
SET "x-oneflow-user-email" IN HEADERS TO user.email
SET "Content-Type" IN HEADERS TO "application/json"
# Step 3: Make the API request to create the contract
SET response TO POST REQUEST TO "{host}/v1/contracts/create" WITH:
- JSON body
- SSL verification
- HEADERS
# Step 4: Check the response status code
IF response.StatusCode EQUALS 200 THEN
SET jsonResponse TO result of parsing response to JSON format
RETURN jsonResponse
ELSE
THROW HttpResponseError
END FUNCTION
Updated about 1 month ago