This API will allow you to send candidates from your website, form, or any other source directly to Jarvi.
Here’s how to proceed:
Get my API keys
If you don’t already have your API keys, follow the steps in the section Get my API keys
Discover the API
Check out the detailed documentation of the API post applicants. It will also be useful to understand the concept of Custom fields
Get inspired by integration examples
Don’t worry, you’re not the first one, and you’ll probably find examples of integrations below that are similar to what you want.
Wordpress (quform)
Here’s an example of a Wordpress integration using the QuForm plugin for forms.
add_action('quform_post_process_{ID_FORM}', function (array $result, Quform_Form $form){
$file_content = file_get_contents( $this->attachments[ 0 ] );
$file_base_64_content = base64_encode( $file_content );
$data = [
'firstName' => $form->getValue('quform_{ID_FORM}_5'),
'lastName' => $form->getValue('quform_{ID_FORM}_7'),
'fullName' => $form->getValue('quform_{ID_FORM}_6') . ' ' . $form->getValue('quform_{ID_FORM}_7'),
'cb9d4872-bfaa-4c57-b1af-91c008883386' => $form->getValue('quform_{ID_FORM}_10'), // Poste
'17fe3ebf-3641-4a94-ac9f-f11a6d429107' => $form->getValue('quform_{ID_FORM}_31'), // Exp SaaS
'6b751e8d-3947-43f9-af52-1db532210c6d' => $form->getValue('quform_{ID_FORM}_12'), // 1e année CDI
'region' => $form->getValue('quform_{ID_FORM}_15'),
'linkedinUrl' => $form->getValue('quform_{ID_FORM}_17'),
'phoneNumbers' => $form->getValue('quform_{ID_FORM}_20'),
'emailAddresses' => $form->getValue('quform_{ID_FORM}_22'),
"resumesFiles": [
{
"data": $file_base_64_content,
"fileName": $this->attachments[ 0 ]->file_name
}
]
];
wp_remote_post('https://functions.prod.jarvi.tech/v1/public-api/rest/applicants', [
'body' => json_encode($data),
'headers' => array(
'Content-Type' => 'application/json',
'X-Api-Key' => '{JARVI_PRIVATE_API_KEY}'
),
]);
return $result;
}, 10, 2);
Webflow (without resume)
Here’s an example of integration in WebFlow. This integration also works for a classic website.
document.querySelector('#form-submit-button').addEventListener('click', function() {
var formElement = document.querySelector('.inscription-candidat-form');
var formData = new FormData(formElement);
var formDataAsObject = {}
for (var [key, value] of formData.entries()) {
console.log(key, value);
formDataAsObject[key] = value
}
if(!formDataAsObject.linkedinUrl) console.error("linkedinUrl is mandatory");
const data = {
"referenceId":"PROJECT-REFERENCE-ID",
...formDataAsObject
}
console.log("data to send",data)
fetch('https://functions.prod.jarvi.tech/v1/public-api/rest/applicants', {
method: 'POST',
mode:'cors',
headers: {
'Content-Type': 'application/json',
'X-Api-Key': 'JARVI_PRIVATE_API_KEY'
},
body: JSON.stringify(data)
})
.then(response => response.json())
.then(data => console.log("data sent",data))
.catch((error) => {
console.error('Error:', error);
});
});
Webflow (WITH resume)
Here’s an example of integration in WebFlow. This integration also works for a classic website.
// Fill those constants with your own values
const FORM_SELECTOR = "#candidature-form";
const SUBMIT_BUTTON_SELECTOR = "#form-submit-button";
const RESUME_INPUT_NAME = "resumesFiles";
const PROJECT_REFERENCE_ID = "PROJECT-REFERENCE-ID";
const JARVI_PRIVATE_API_KEY = "YOUR JARVI PRIVATE API KEY";
// Helper function to read file as base64
const readFileAsBase64 = (file) => {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = (event) => resolve(event.target.result);
reader.onerror = (error) => reject(error);
reader.readAsDataURL(file);
});
};
// Helper function to validate form data
const validateFormData = (formData) => {
if (!formData.linkedinUrl) {
throw new Error("LinkedIn URL is mandatory");
}
return true;
};
// Main form submission handler
document.querySelector(SUBMIT_BUTTON_SELECTOR).addEventListener("click", async function (event) {
event.preventDefault(); // Prevent default form submission
try {
const formElement = document.querySelector(FORM_SELECTOR);
if (!formElement) {
throw new Error("Form element not found");
}
// Convert FormData to object
const formData = new FormData(formElement);
const formDataAsObject = Object.fromEntries(formData.entries());
// Validate form data
validateFormData(formDataAsObject);
// Get and validate file
const fileInput = formElement.querySelector(`input[name="${RESUME_INPUT_NAME}"]`);
if (!fileInput) {
throw new Error("Resume input field not found");
}
const file = fileInput.files[0];
if (!file) {
throw new Error("No file uploaded");
}
// Read file and prepare data
const base64Data = await readFileAsBase64(file);
const resumesFiles = [
{
fileName: file.name,
data: base64Data,
},
];
const data = {
referenceId: "PROJECT-REFERENCE-ID", // Update with your project reference ID
...formDataAsObject,
resumesFiles,
};
console.log("Sending data:", data);
// Send data to API
const response = await fetch("https://functions.prod.jarvi.tech/v1/public-api/rest/v2/applicants", {
method: "POST",
mode: "cors",
headers: {
"Content-Type": "application/json",
"X-Api-Key": JARVI_PRIVATE_API_KEY,
},
body: JSON.stringify(data),
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const responseData = await response.json();
console.log("Data sent successfully:", responseData);
// Optional: Show success message to user
alert("Application submitted successfully!");
} catch (error) {
console.error("Error:", error);
alert(`Error: ${error.message}`);
}
});