API error response while uploading resume

Forum for users and developers of Bullhorn's API service.

Moderators: StaffingSupport, s.emmons, BullhornSupport

Jhunt
User
Posts: 4
Joined: Thu Sep 19, 2013 12:57 am

API error response while uploading resume

Post by Jhunt » Thu Sep 19, 2013 1:32 am

Hi

These are some of the errors we receive while using the bullhorn api.

1. During resume parsing (html conversion error)
Document type : application/octet-stream, application/pdf
Error received : Parse failed: Html conversion error

2. During uploading txt file (invalid format)
Document type: text/plain
Error received : "Invalid format: Must be one of TEXT, HTML, PDF, DOC, DOCX, RTF, XML, VCARD, RFC822, ODT."

3. During a .doc file upload (Rex)
Document type : application/octet-stream
Error received : Parse failed: Rex has not been initialized

Please help us fix this.

Cheers
Sanjay

Sean.Hayes
User
Posts: 10
Joined: Wed Sep 18, 2013 9:19 am

Re: API error response while uploading resume

Post by Sean.Hayes » Thu Sep 19, 2013 10:14 am

Hello Sanjay,
As far as #1 and 2 that you gave me below, can you specify the specific call that you made so I can take a look. I will just need to see a couple examples in order to further look at the issue and why it is not working for you. Also, just let me know which version of the API you are using.

In regards to #3, the Rex error you are seeing does happen from time to time. The parser fails for a few different reasons, one including the possible format of the resume causing the error. I would suggest to try again on that one and see if that works. Feel free to send me an example for that call if you would like as well.
Sean Hayes | Senior Technical Support Analyst

Jhunt
User
Posts: 4
Joined: Thu Sep 19, 2013 12:57 am

Re: API error response while uploading resume

Post by Jhunt » Fri Sep 20, 2013 3:52 am

Version
---------
I have used the REST API. I think there is only version 1.1
I am following this pdf to develop:
http://developer.bullhorn.com/sites/def ... TAPI_0.pdf


Different file uploads, api call urls, and responses
----------------------------------------------------------
resume.doc
file name:resume.doc, doc type : application/msword
Response: {"resume":{"name":"resume.doc","type":"application\\/msword","tmp_name":"\\/tmp\\/phpjlZa7M","error":0,"size":43136},"format":"doc"}
URL: https://rest0.bullhornstaffing.com/rest ... format=doc
Parse failed: Html conversion error

resume.pdf
file name:resume.pdf, doc type : application/pdf
{"resume":{"name":"resume.pdf","type":"application\\/pdf","tmp_name":"\\/tmp\\/php8ADnLy","error":0,"size":252814},"format":"pdf"}
URL: https://rest0.bullhornstaffing.com/rest ... format=pdf
Parse failed: null

resume.txt
file name:resume.txt, doc type : text/plain
URL: https://rest0.bullhornstaffing.com/rest ... format=txt
Invalid format: Must be one of TEXT, HTML, PDF, DOC, DOCX, RTF, XML, VCARD, RFC822, ODT.

resume.odt
file name:resume.odt, doc type : application/vnd.oasis.opendocument.text
{"resume":{"name":"resume.odt","type":"application\\/vnd.oasis.opendocument.text","tmp_name":"\\/tmp\\/phpUZjLOM","error":0,"size":26762},"format":"odt"}
URL: https://rest0.bullhornstaffing.com/rest ... format=odt
Parse failed: Html conversion error


Rex error
-----------
When this response comes in, if we try one more time the submit button it is working.

Jhunt
User
Posts: 4
Joined: Thu Sep 19, 2013 12:57 am

Re: API error response while uploading resume

Post by Jhunt » Fri Sep 20, 2013 3:54 am

I have attached some resumes we tried
Attachments
resumes.zip
I have attached some resumes we tried
(52.17 KiB) Downloaded 718 times

Alliance
User
Posts: 40
Joined: Mon Feb 18, 2013 12:16 pm

Re: API error response while uploading resume

Post by Alliance » Thu Sep 26, 2013 10:27 am

FWIW, we get the "Parse failed: Rex has not been initialized" regularly. Our workaround is to loop that call and hit that resume parser over and over until it works or we hit a maximum number of attempts (ours is set at 10) where we are fairly certain its not the parser but the resume at fault.

Quite often it takes 3 to 5 attempts before the parse stops returning "Parse failed: Rex has not been initialized" and instead returns the parsed resume.

File types you could validate client-side and avoid the call to the parser entirely with invalid file types, let the user know they should be providing a resume in one of the valid file types.

Jhunt
User
Posts: 4
Joined: Thu Sep 19, 2013 12:57 am

Re: API error response while uploading resume

Post by Jhunt » Mon Sep 30, 2013 12:31 am

Regarding Resume upload
------------------------------
Okay we will look for solutions to loop through resume parsing till that succeeds, but that will take a while to submits the resume, making client looking at screen. Or we need to do it in the background.

Which way you suggest online processing, or scheduled job?

Regarding application type
--------------------------------
resume.txt
file name:resume.txt, doc type : text/plain
URL: https://rest0.bullhornstaffing.com/rest ... format=txt
Invalid format: Must be one of TEXT, HTML, PDF, DOC, DOCX, RTF, XML, VCARD, RFC822, ODT.

In this case we are uploading a plain text type (text/plain), which is supported by the bullhorn. Still we are getting application type error.That is not clear to me.

Alliance
User
Posts: 40
Joined: Mon Feb 18, 2013 12:16 pm

Re: API error response while uploading resume

Post by Alliance » Mon Sep 30, 2013 9:37 am

It doesn't take long to loop. I don't know what technologies or systems you are using on your front and back end, so it's tough to suggest a solution. Most developers use either a simple form POST to submit a resume or else an asynchronous request which submits the resume in the background so that the submitter doesn't have to leave the page they are on. I would not use a scheduled task or cron job for this, but that's up to you.

jeffsacco
User
Posts: 6
Joined: Thu Jul 25, 2013 1:32 pm

Re: API error response while uploading resume

Post by jeffsacco » Sat Oct 05, 2013 11:39 am

Hello

I am having a very similar error. I have attached the code below that I am using to make the call. I have removed out client id, client secret, username and password for security reasons. This file is being called after a file upload which would be the resume:

Code: Select all

<?php

define('CLIENT_ID', '');
define('CLIENT_SECRET', '');
define('USER', '');
define('PASS', '');


function getAuthCode()
{
$url = 'https://auth.bullhornstaffing.com/oauth/authorize?client_id='.CLIENT_ID.'&response_type=code&action=Login&username='.USER.'&password='.PASS;

$curl = curl_init( $url );
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HEADER, true);
curl_setopt($curl, CURLOPT_AUTOREFERER, true);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 120);
curl_setopt($curl, CURLOPT_TIMEOUT, 120);

$content = curl_exec( $curl );
curl_close( $curl );

if(preg_match('#Location: (.*)#', $content, $r)) {
$l = trim($r[1]);
$temp = preg_split("/code=/", $l);
$authcode = $temp[1];
}

return $authcode;
}

function doBullhornAuth($authCode)
{
	$url = 'https://auth.bullhornstaffing.com/oauth/token?grant_type=authorization_code&code='.$authCode.'&client_id='.CLIENT_ID.'&client_secret='.CLIENT_SECRET;

	$options = array(
	CURLOPT_RETURNTRANSFER => 1,
	CURLOPT_POST => true,
	CURLOPT_POSTFIELDS => array()
	);

	$ch = curl_init( $url );
	curl_setopt_array( $ch, $options );
	$content = curl_exec( $ch );

	curl_close( $ch );

	return $content;

}

function doBullhornLogin($accessToken)
{
	$url = 'https://rest.bullhornstaffing.com/rest-services/login?version=*&access_token='.$accessToken;
	$curl = curl_init( $url );
	curl_setopt($curl, CURLOPT_URL, $url);
	curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
	$content = curl_exec( $curl );
	curl_close( $curl );
	return $content;
}

function doBullhornJobQuery($BhRestToken, $BhURL)
{
	$data = "query/JobOrder?fields=id,status&where=id>=1&orderBy=-id&count=5000&BhRestToken=".$BhRestToken;

	$tuCurl = curl_init();
		curl_setopt($tuCurl, CURLOPT_URL, $BhURL.$data);
		curl_setopt($tuCurl, CURLOPT_PORT , 443);
		curl_setopt($tuCurl, CURLOPT_VERBOSE, 0);
		curl_setopt($tuCurl, CURLOPT_HEADER, 0);
		curl_setopt($tuCurl, CURLOPT_SSLVERSION, 3); 
		curl_setopt($tuCurl, CURLOPT_SSL_VERIFYPEER, 1); 
		curl_setopt($tuCurl, CURLOPT_RETURNTRANSFER, 1);
	$tuData = curl_exec($tuCurl);
	curl_close($tuCurl);

	return $tuData;
}

function doBullhornEventJobQuery($BhRestToken, $BhURL)
{
	$data = "query/JobOrder?fields=title,id,address,dateAdded,employmentType,skillList,dateClosed,dateEnd,categories,status,publishedZip,isPublic&where=id>=10123%20AND%20isPublic=1&orderBy=-id&count=20&BhRestToken=".$BhRestToken;
	
	$tuCurl = curl_init();
		curl_setopt($tuCurl, CURLOPT_URL, $BhURL.$data);
		curl_setopt($tuCurl, CURLOPT_PORT , 443);
		curl_setopt($tuCurl, CURLOPT_VERBOSE, 0);
		curl_setopt($tuCurl, CURLOPT_HEADER, 0);
		curl_setopt($tuCurl, CURLOPT_SSLVERSION, 3); 
		curl_setopt($tuCurl, CURLOPT_SSL_VERIFYPEER, 1); 
		curl_setopt($tuCurl, CURLOPT_RETURNTRANSFER, 1);
	$tuData = curl_exec($tuCurl);
	curl_close($tuCurl);

	return $tuData;
}

function doBullhornEventResume($BhRestToken, $BhURL, $file_upload)
{
	$data = "resume/parseToCandidate?format=doc&BhRestToken=".$BhRestToken;

	$file = fopen($file_upload, 'r');
	$size = filesize($file_upload);
	$filedata = fread($file,$size);

	$post = array('extra_info' => '123456','file_contents'=>'@'.$file_upload);

	$tuCurl = curl_init();
		curl_setopt($tuCurl, CURLOPT_URL, $BhURL.$data);
		curl_setopt($tuCurl, CURLOPT_VERBOSE, 1);
		curl_setopt($tuCurl, CURLOPT_HTTPHEADER, array('Content-type: multipart/form-data'));
		curl_setopt($tuCurl, CURLOPT_POST, true);
		curl_setopt($tuCurl, CURLOPT_RETURNTRANSFER, true);
		curl_setopt($tuCurl, CURLOPT_POSTFIELDS, $post); 
	$tuData = curl_exec($tuCurl);
	curl_close($tuCurl);

	return $tuData;
}

function doBullhornEventCreateCanidate($BhRestToken, $BhURL, $information)
{
	$data = "entity/Candidate?BhRestToken=".$BhRestToken;

	$decoded = json_decode($information);

	$canidate_info = $decoded->candidate;

	$json_canidate_info = json_encode($canidate_info);

	$tuCurl = curl_init();
		curl_setopt($tuCurl, CURLOPT_URL, $BhURL.$data);
		curl_setopt($tuCurl, CURLOPT_VERBOSE, 1);
		curl_setopt($tuCurl, CURLOPT_CUSTOMREQUEST, "PUT"); 
		curl_setopt($tuCurl, CURLOPT_RETURNTRANSFER, true);
		curl_setopt($tuCurl, CURLOPT_POSTFIELDS, $json_canidate_info); 
	$tuData = curl_exec($tuCurl);

	curl_close($tuCurl);

	return $tuData;
}

function doBullhornEventAddCanidateResume($BhRestToken, $BhURL, $information, $file_upload)
{
	$data = "file/Candidate/".$information."/raw?externalID=Portfolio&fileType=SAMPLE&BhRestToken=".$BhRestToken;

	$file = fopen($file_upload, 'r');
	$size = filesize($file_upload);
	$filedata = fread($file,$size);
	
	$post = array('extra_info' => '123456','file_contents'=>'@'.$file_upload);
	
	$tuCurl = curl_init();
		curl_setopt($tuCurl, CURLOPT_URL, $BhURL.$data);
		curl_setopt($tuCurl, CURLOPT_VERBOSE, 1);
		curl_setopt($tuCurl, CURLOPT_HTTPHEADER, array('Content-type: multipart/form-data'));
		curl_setopt($tuCurl, CURLOPT_POST, true);
		curl_setopt($tuCurl, CURLOPT_CUSTOMREQUEST, "PUT"); 
		curl_setopt($tuCurl, CURLOPT_RETURNTRANSFER, true);
		curl_setopt($tuCurl, CURLOPT_POSTFIELDS, $post); 
	$tuData = curl_exec($tuCurl);
	
	curl_close($tuCurl);

	return $tuData;
}

function doBullhornEventCreateCanidateEducation($BhRestToken, $BhURL, $id, $information)
{
	$data = "entity/CandidateEducation?BhRestToken=".$BhRestToken;

	$decoded = json_decode($information);

	$canidate_info = $decoded->candidateEducation;
	
	$num = count($canidate_info);

	for ($i=0; $i < $num; $i++) 
	{ 

			$arr = array_pop($canidate_info);

			$idd = new StdClass();

			$idd->id = $id;

			$arr->candidate = $idd;
			$json_canidate_info = json_encode($arr);
	
			$tuCurl = curl_init();
				curl_setopt($tuCurl, CURLOPT_URL, $BhURL.$data);
				curl_setopt($tuCurl, CURLOPT_VERBOSE, 1);
				curl_setopt($tuCurl, CURLOPT_CUSTOMREQUEST, "PUT"); 
				curl_setopt($tuCurl, CURLOPT_RETURNTRANSFER, true);
				curl_setopt($tuCurl, CURLOPT_POSTFIELDS, $json_canidate_info); 
			$tuData = curl_exec($tuCurl);
			curl_close($tuCurl);
	}

	return $tuData;
}

function doBullhornEventGetCanidateInfo($BhRestToken, $BhURL, $information)
{
	$data = "/entity/Candidate/".$information."?fields=*&BhRestToken=".$BhRestToken;
	
	$tuCurl = curl_init();
		curl_setopt($tuCurl, CURLOPT_URL, $BhURL.$data);
		curl_setopt($tuCurl, CURLOPT_VERBOSE, 1);
		curl_setopt($tuCurl, CURLOPT_CUSTOMREQUEST, "GET"); 
		curl_setopt($tuCurl, CURLOPT_RETURNTRANSFER, true);
	$tuData = curl_exec($tuCurl);
	
	curl_close($tuCurl);

	return $tuData;
}

function doBullhornEventGetCanidateFileInfo($BhRestToken, $BhURL, $information)
{
	$data = "entityFiles/Candidate/".$information."?BhRestToken=".$BhRestToken;

	$tuCurl = curl_init();
		curl_setopt($tuCurl, CURLOPT_URL, $BhURL.$data);
		curl_setopt($tuCurl, CURLOPT_VERBOSE, 1);
		curl_setopt($tuCurl, CURLOPT_CUSTOMREQUEST, "GET"); 
		curl_setopt($tuCurl, CURLOPT_RETURNTRANSFER, true);
	$tuData = curl_exec($tuCurl);
	
	curl_close($tuCurl);

	return $tuData;
}

try 
{
	$authCode = getAuthCode();//echo $authCode;die;
	$auth = doBullhornAuth($authCode);//echo $auth;die;
	$tokens = json_decode($auth);//print '<pre>';print_r($tokens);die;
	$session = doBullhornLogin($tokens->access_token);

} catch (Exception $e) {
	error_log($e->getMessage());
}

$jeff = json_decode($session);

$joborder = doBullhornEventResume($jeff->BhRestToken, $jeff->restUrl, $file_location);

$new_canidate = doBullhornEventCreateCanidate($jeff->BhRestToken, $jeff->restUrl, $joborder);

$get_id = json_decode($new_canidate);

doBullhornEventAddCanidateResume($jeff->BhRestToken, $jeff->restUrl, $get_id->changedEntityId, $file_location);

doBullhornEventGetCanidateFileInfo($jeff->BhRestToken, $jeff->restUrl, $get_id->changedEntityId);


?>

The error I am getting is when I am trying to upload the file to attach to the candidate. I keep getting this error:
{ "errorCode" : 400, "errorMessage" : "Invalid file extension!" }{ "EntityFiles" : [ ] }
My concern about this is when I upload the resume to be parsed into the candidate information, everything works fine yet when I go to attach it to the candidate, I get this error. Not sure why there is a difference between the two.

Furthermore. and this is the real odd part, if I don't use the uploaded file and instead substitute it with a resume file located in the same directory at this file, it works fine.

If someone there could provide some sort of solution to this, that would be great. Or if you can point out my flaw.

Thank you.

Alliance
User
Posts: 40
Joined: Mon Feb 18, 2013 12:16 pm

Re: API error response while uploading resume

Post by Alliance » Mon Oct 07, 2013 11:27 am

jeffsacco,
I assume this error is coming from the doBullhornEventAddCanidateResume() call?
Is "SAMPLE" a valid file type? Are you including a format=$file_extension parameter on your URL?

The parsing call is probably different than the attach file to candidate record call.

Why use fopen when you can directly POST a file attachment?

Code: Select all

        // prepare POST args
        $data = array(
            "file[]" => '@' . $file_path
        );


        // cURL options
        $curl_opts = array(
            CURLOPT_POST           => true,
            CURLOPT_POSTFIELDS     => $data,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_HTTPHEADER     => array( "Content-type: multipart/form-data" ),
            CURLOPT_FOLLOWLOCATION => true,
        );


jtam
User
Posts: 13
Joined: Tue Jan 27, 2009 4:01 pm

Re: API error response while uploading resume

Post by jtam » Tue Oct 15, 2013 6:46 pm

I am getting the same error trying to attach a resume with a Candidate.

stdClass Object ( [errorCode] => 400 [errorMessage] => Invalid file extension! )


Code: Select all

function attachCandidateResume($candidateID, $data)
{

$url = $_SESSION['restURL'] . '/file/Candidate/' . $candidateID . '/raw?externalID=Portfolio&filetype=SAMPLE&BhRestToken=' . $_SESSION['BhRestToken'];

//$data is the full path to a file named Test.doc

$file = array("file[]" => '@' . $data);

$curl = curl_init( $url ); 
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_HTTPHEADER, array( "Content-Type: multipart/form-data"));
curl_setopt($curl, CURLOPT_VERBOSE, 1);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "PUT");
curl_setopt($curl, CURLOPT_POSTFIELDS, $file);

$content = curl_exec( $curl );
curl_close( $curl );
return $content;
}

rcross
User
Posts: 11
Joined: Thu Sep 12, 2013 10:21 am

Re: API error response while uploading resume

Post by rcross » Tue Oct 22, 2013 3:16 pm

Jtam,

What type of file extension were you trying to upload?

-rcross

jtam
User
Posts: 13
Joined: Tue Jan 27, 2009 4:01 pm

Re: API error response while uploading resume

Post by jtam » Tue Oct 22, 2013 5:24 pm

.doc or .docx

rcross
User
Posts: 11
Joined: Thu Sep 12, 2013 10:21 am

Re: API error response while uploading resume

Post by rcross » Wed Oct 23, 2013 3:06 pm

May I have the full request URL

jtam
User
Posts: 13
Joined: Tue Jan 27, 2009 4:01 pm

Re: API error response while uploading resume

Post by jtam » Wed Oct 23, 2013 3:48 pm

$url = $_SESSION['restURL'] . '/file/Candidate/' . $candidateID . '/raw?externalID=Portfolio&filetype=SAMPLE&BhRestToken=' . $_SESSION['BhRestToken'];

i.e.
https://rest3.bullhornstaffing.com/rest ... n=xxxxxxxx

rcross
User
Posts: 11
Joined: Thu Sep 12, 2013 10:21 am

Re: API error response while uploading resume

Post by rcross » Mon Oct 28, 2013 9:24 am

Jtam,

I have been looking into this, do you have a Request Body?

Post Reply