Getting Startedπ︎
First Stepsπ︎
-
This documentation is for technical details about the API only. Before starting your integration, you should read the Product Documentation for the products you plan to integrate with. We will show you the most important information on how to create a quick and successful integration.
- Resume Parsing API
- Resume Parsing
- Job Parsing
- Search & Match
- Then, read the Acceptable Use Policy that will require your programming expertise in order to be in compliance.
- Review the code samples in the section below.
Code Samplesπ︎
Here we have a few code samples to get you up and running quickly:
```csharp //go to https://cloud.textkernel.com/tx/console/assets/downloads/v9/Schemas/ResumeSchema.zip to download necessary Resume.cs file
string filePath = "resume.docx"; byte[] fileBytes = File.ReadAllBytes(filePath); dynamic data = new { DocumentAsBase64String = Convert.ToBase64String(fileBytes), RevisionDate = File.GetLastWriteTime(filePath).ToString("yyyy-MM-dd") //other options here (see https://developer.textkernel.com/tx-platform/v9/resume-parser/api/) };
//use the correct URL for the data center associated with your account, or your own server if you are self-hosted string url = ".../v9/parser/resume"; string json = JsonSerializer.Serialize(data);
string strResume = "";
using (WebClient client = new WebClient()) { client.Headers[HttpRequestHeader.ContentType] = "application/json"; client.Headers[HttpRequestHeader.Accept] = "application/json"; client.Headers["Tx-AccountId"] = "12345678"; client.Headers["Tx-ServiceKey"] = "eumey7feY5zjeWZW397Jks6PBj2NRKSH"; //This line is important to preserve utf8 characters client.Encoding = System.Text.Encoding.UTF8;
string result = client.UploadString(url, "POST", json);
//for response properties and types, see https://developer.textkernel.com/tx-platform/v9/resume-parser/api/
strResume = JsonSerializer.Deserialize(result).GetProperty("Value").GetProperty("ParsedDocument").ToString();
}
Sovren.External.Resume resume = null; //in order to use the XSD-generated class here, we must go from JSON to XML first XmlDocument node = JsonConvert.DeserializeXmlNode(strResume); XmlSerializer serializer = new XmlSerializer(typeof(Sovren.External.Resume)); using (StringReader sr = new StringReader(node.InnerXml)) { resume = serializer.Deserialize(sr) as Sovren.External.Resume; }
Console.WriteLine(resume.StructuredXMLResume.ContactInfo.PersonName.FormattedName); ```
```javascript //https://developer.mozilla.org/en-US/docs/Using_files_from_web_applications var file = $("#input").files[0]; var revisionDate = (new Date(file.lastModified)).toISOString().substring(0, 10); var reader = new FileReader();
reader.onload = function (event) { //the Base64 library can be found at http://cloud.textkernel.com/console/assets/downloads/v10/Libs/base64.zip var base64Text = Base64.encodeArray(event.target.result);
var data = {
"DocumentAsBase64String": base64Text,
"RevisionDate": revisionDate
//other options here (see https://developer.textkernel.com/tx-platform/v9/resume-parser/api/)
};
//use the correct URL for the data center associated with your account, or your own server if you are self-hosted
//NOTE: this is shown for demonstration purposes only, you should never embed your credentials
// in javascript that is going to be distributed to end users. Instead, your javascript should
// call a back-end service which then makes the POST to Textkernel's API
$.ajax({
"url": ".../v9/parser/resume",
"method": "POST",
"crossDomain": true,
"headers": {
"Accept": "application/json",
"Content-Type": "application/json",
"Tx-AccountId": "12345678",
"Tx-ServiceKey": "eumey7feY5zjeWZW397Jks6PBj2NRKSH"
},
"data": JSON.stringify(data)
});
}
// when the file is read it triggers the onload event above. reader.readAsArrayBuffer(file); ```
```python import base64 import requests #this module will need to be installed import json import os.path import datetime
base64str = '' filePath = 'resume.docx'
open the file, encode the bytes to base64, then decode that to a UTF-8 stringπ︎
with open(filePath, 'rb') as f: base64str = base64.b64encode(f.read()).decode('UTF-8')
epochSeconds = os.path.getmtime(filePath) revisionDate = datetime.datetime.fromtimestamp(epochSeconds).strftime("%Y-%m-%d")
use the correct URL for the data center associated with your account, or your own server if you are self-hostedπ︎
url = ".../v9/parser/resume" payload = { 'DocumentAsBase64String': base64str, 'RevisionDate': revisionDate #other options here (see https://developer.textkernel.com/tx-platform/v9/resume-parser/api/) }
headers = { 'accept': "application/json", 'content-type': "application/json", 'tx-accountid': "12345678", 'tx-servicekey': "eumey7feY5zjeWZW397Jks6PBj2NRKSH", }
make the request, NOTE: the payload must be serialized to a json stringπ︎
response = requests.request("POST", url, data=json.dumps(payload), headers=headers) responseJson = json.loads(response.content)
load ParsedDocument string into json objectπ︎
parsedDoc = json.loads(responseJson['Value']['ParsedDocument'])
access the ParsedDocument properties with simple JSON syntax:π︎
print(parsedDoc['Resume']['StructuredXMLResume']['ContactInfo'])
for response properties and types, see https://developer.textkernel.com/tx-platform/v9/resume-parser/api/π︎
```
```ruby require 'uri' require 'net/http' require 'net/https' require 'base64' require 'json'
file_path = 'resume.docx' file_data = IO.binread(file_path) revision_date = File.mtime(file_path).to_s[0,10]
Encode the bytes to base64π︎
base_64_file = Base64.encode64(file_data) data = { "DocumentAsBase64String" => base_64_file, "RevisionDate" => revision_date #other options here (see https://developer.textkernel.com/tx-platform/v9/resume-parser/api/) }.to_json
use the correct URL for the data center associated with your account, or your own server if you are self-hostedπ︎
uri = URI.parse(".../v9/parser/resume") https = Net::HTTP.new(uri.host,uri.port) https.use_ssl = true
headers = { 'Content-Type' => 'application/json', 'Accept' => 'application/json', 'Tx-AccountId' => '12345678', # use your account id here 'Tx-ServiceKey' => 'eumey7feY5zjeWZW397Jks6PBj2NRKSH', # use your service key here }
req = Net::HTTP::Post.new(uri.path, initheader = headers) req.body = data
res = https.request(req)
Parse the response body into an objectπ︎
respObj = JSON.parse(res.body)
Parse the ParsedDocument string into an object (for response properties and types, see https://developer.textkernel.com/tx-platform/v9/resume-parser/api/)π︎
parsedDoc = JSON.parse(respObj["Value"]["ParsedDocument"])
Access properties such as the GivenName and TextResumeπ︎
givenName = parsedDoc["Resume"]["StructuredXMLResume"]["ContactInfo"]["PersonName"]["GivenName"] resumeText = parsedDoc["Resume"]["NonXMLResume"]["TextResume"] ```
```java //import java.io.; //import java.nio.file.; //import java.net.; //import java.util.;
// Specify filename and compute path Path filePath = Paths.get("resume.docx");
// Open file, encode contents to base64, then decode to UTF-8 byte[] encoded = Base64.getEncoder().encode(Files.readAllBytes(filePath)); String base64Str = new String(encoded, "UTF-8");
String revisionDate = Files.getLastModifiedTime(filePath).toString().substring(0, 10);
// Create connection object, based on the given url-name //use the correct URL for the data center associated with your account, or your own server if you are self-hosted URL url = new URL(".../v9/parser/resume"); HttpURLConnection connection = (HttpURLConnection)url.openConnection();
// Properties in order to ensure succesful POST-request connection.setUseCaches(false); connection.setDoInput(true); connection.setDoOutput(true);
// Specify request-method and headers connection.setRequestMethod("POST"); connection.setRequestProperty("Content-Type", "application/json"); connection.setRequestProperty("accept", "application/json");
// Specify your credentials connection.setRequestProperty("Tx-AccountId", "12345678"); connection.setRequestProperty("Tx-ServiceKey", "eumey7feY5zjeWZW397Jks6PBj2NRKSH");
// Construct payload in JSON-format // (This is a very primitive way to do so, as not to have any external dependencies // feel free to use your preferred json-library) String payload = "{ \"DocumentAsBase64String\": \"" + base64Str + "\", \"RevisionDate\": \"" + revisionDate + "\" }"; //other options here (see https://developer.textkernel.com/tx-platform/v9/resume-parser/api/)
// Send payload BufferedWriter bw = new BufferedWriter( new OutputStreamWriter(new DataOutputStream(connection.getOutputStream()), "UTF-8")); bw.write(payload); bw.flush(); bw.close();
// Read response int responseCode = connection.getResponseCode(); BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8")); String inputLine; StringBuffer response = new StringBuffer(); while ((inputLine = in.readLine()) != null) { response.append(inputLine); } in.close();
// (Optional) Output response details System.out.println(responseCode); System.out.println(response.toString()); //for response properties and types, see https://developer.textkernel.com/tx-platform/v9/resume-parser/api/ ```
```php //If your PHP installation doesn't have an up-to-date CA root certificate bundle, download the one at the curl website and save it on your server: //http://curl.haxx.se/docs/caextract.html //Then set a path to it in your php.ini file, e.g. on Windows: //curl.cainfo=c:\php\cacert.pem
// open the file $filepath = "resume.docx"; $handle = fopen($filepath, "r"); $contents = fread($handle, filesize($filepath)); fclose($handle);
$revisionDate = date("Y-m-d", filemtime($filepath));
//encode to base64 $base64str = base64_encode($contents); $data = ["DocumentAsBase64String" => $base64str, "RevisionDate" => $revisionDate]; //other options here (see https://developer.textkernel.com/tx-platform/v9/resume-parser/api/)
//use the correct URL for the data center associated with your account, or your own server if you are self-hosted $url = ".../v9/parser/resume";
//setup curl to make the REST call, you can use an external library //such as Guzzle if you prefer: http://guzzle.readthedocs.io $curl = curl_init(); curl_setopt($curl, CURLOPT_POST, 1); curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($curl, CURLOPT_URL, $url); curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$headers = [ "accept: application/json", "content-type: application/json; charset=utf-8", "tx-accountid: 12345678", "tx-servicekey: eumey7feY5zjeWZW397Jks6PBj2NRKSH" ]; curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($curl); curl_close($curl);
echo $result;//this is a string, you can now use json_decode if you like //for response properties and types, see https://developer.textkernel.com/tx-platform/v9/resume-parser/api/ ```
```javascript const http = require('https'); const fs = require('fs');
var filePath = "resume.docx"; var buffer = fs.readFileSync(filePath); var base64Doc = buffer.toString('base64');
var revisionDate = (new Date(fs.statSync(filePath).mtimeMs)).toISOString().substring(0, 10);
//other options here (see https://developer.textkernel.com/tx-platform/v9/resume-parser/api/) var postData = JSON.stringify({ 'DocumentAsBase64String': base64Doc, 'RevisionDate': revisionDate });
//use https://api.eu.textkernel.com/tx/v9/parser/resume if your account is in the EU data center or //use https://api.au.textkernel.com/tx/v9/parser/resume if your account is in the AU data center //for self-hosted use https://{your-server}/v9/parser/resume var options = { host: 'api.us.textkernel.com', protocol: 'https:', path: 'tx/v9/parser/resume', method: 'POST', headers: { 'Tx-AccountId': '12345678', 'Tx-ServiceKey': 'eumey7feY5zjeWZW397Jks6PBj2NRKSH', 'Accept': 'application/json', 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(postData) } };
var request = http.request(options, function (response) { response.setEncoding('utf8');
var responseAsString = '';
response.on('data', (chunk) => {
responseAsString += chunk;
});
response.on('end', () => {
var responseAsJson = JSON.parse(responseAsString);
console.log(responseAsJson.Info);
var parsedDocString = responseAsJson.Value.ParsedDocument;
console.log(parsedDocString);
var parsedDocJson = JSON.parse(parsedDocString);
//now you can consume the parsedDocJson
});
});
request.write(postData); request.end(); ```
Info
All above code samples are provided without warranty and are not necessarily indicative of best practices.
Standard Transaction Costπ︎
Endpointsπ︎
Info
Our REST API is also documented using Swagger. Follow the links below for the appropriate data center to access an HTML page where you can make sample requests.
| US Data Center | EU Data Center | |
|---|---|---|
| HTTPS | https://api.us.textkernel.com/tx/v9/ | https://api.eu.textkernel.com/tx/v9/ |
Authenticationπ︎
Our REST API handles authentication via the Tx-AccountId and Tx-ServiceKey headers. These keys were generated during account creation and send to the contacts listed on the account. If authentication fails we return a 401 Unathorized HTTP Status Code.
The most common causes for unauthorized exceptions are:
- Not including the headers in the request
- Making requests to the wrong data center. If you have questions about which data center your account is setup for contact TXsupport@bullhorn.com
If you recieve a 403 Forbidden Access exception, please confirm that you are using https. We have deprecated the use of unsecured http connections in this verison.
Request Headersπ︎
| Header | Data Type | Required | Description |
|---|---|---|---|
| Tx-AccountId | string | Yes | The Account ID that is provided to you when establishing your Service Account. |
| Tx-ServiceKey | string | Yes | The Service key that is provided to you for access to your accountβs available credits. |
| Content-Type | string | Yes | Indicates the media type of the incoming request body. The only supported value is application/json. |
| Tx-TrackingTag | string | No | An optional value that you can use for tracking API usage in the Tx Console. Comma-separated values are accepted here, and the max length is 100 characters. |
Versioningπ︎
We continuously deploy bug fixes and new features to our API. We limit breaking changes to new versions deployed to new urls unless the change is to fix an error in the output*. In the top of our documentation site you can change the API version of the documentation.
Release notes can be found here.
| APIΒ Version | Status | Notes |
|---|---|---|
| VersionΒ 10 | Suggested (new customers/projects) | This is the same as v9 under-the-hood, but features an entirely new/modern input/output structure and official SDKs. |
| VersionΒ 9 | Suggested (existing customers/projects) | This version is still receiving updates and is fully supported. Full release notes can be found here. |
* In order to keep up with the industry standards we occasionally will make changes including, but not limited to, security and infrastructure areas. Whenever customer impact is foreseen, we'll do our best to communicate at least 30 days in advance.
HTTP Status Codesπ︎
Our API uses conventional HTTP status codes to describe the overall status of the transaction. The specific code we return are detailed below and mapped to the Info.Code values we return for every transaction:
| HTTP Status Code | Info.Code | Description |
|---|---|---|
| 200 - OK | Success, WarningsFoundDuringParsing, PossibleTruncationFromTimeout, SomeErrors | The transaction was successful |
| 400 - Bad Request | MissingParameter, InvalidParameter, InsufficientData, DataNotFound, CoordinatesNotFound, ConstraintError | Unable to process request |
| 401 - Unauthorized | AuthenticationError, Unauthorized | The AccountId and/or ServiceKey were invalid |
| 403 - Forbidden | N/A | The request was made using http instead of https. |
| 404 - Not Found | DataNotFound | The requested asset wasn't found. |
| 408 - Request Timeout | Timeout | The transaction reached its timeout limit. |
| 409 - Conflict | DuplicateAsset | The request could not be completed due to a conflict with the current state of the target resource. |
| 413 - Payload Too Large | RequestTooLarge | The request is too large to be processed by the server. The max file size is ~16MB on disk. |
| 422 - Unprocessable Entity | ConversionException | The request made was syntactically correct, but the provided document was unable to be converted to text. |
| 429 - Too Many Requests | TooManyRequests | Your submission has been rejected without being processed because you were exceeding the allowable batch parsing transaction concurrency limit per the AUP. You have been charged for submitting the transaction. It is your responsibility to resubmit this transaction after you correct the process which caused the concurrency problem. |
| 500 - Internal Server Error | UnhandledException | An unexpected issue occurred (these are extremely rare). |