Payslip

Comprehensive capture and extraction of Payslips.

The verification of payslips enables individuals and institutions to confirm the authenticity and accuracy of an individual's income details. This validation is critical for securing rental accommodations, obtaining mortgage approvals, and fostering trust in financial transactions that depend on accurate income documentation.

Introduction

Datakeen's OCR service automatically extracts information from payslips.

  • Information is captured as structured data and can be extracted as a .json file through our API.
Extracted informationControls
- Company name
- Company address
- Company SIRET number
- Period
- Start date
- APE code
- Job / Position
- Employee's full name
- Employee's address
- Social security number
- Gross salary
- Net before tax
- Cumulative taxable net income for the year
- Net payable
- Net taxable income
- Social security ceiling for the month
- Paid leave balance
- matchName
- matchAddress
- nSSConformity
- periodConformity
- companyAddressConformity
- companyNameConformity
- siretConformity
- apeCodeConformity
- rentLocationLessThan100KM
- paymentVariance
- SSCeilingConformity
- joiningDateConformity

Setting up the API

The synchronous API model extracts data from payslips in real time.

📘

API token is required

In order to perform any call, you will need an API token that can be retrieved thanks your API credentials. To learn about authentification, please refer to this page

curl --request POST \
     --url https://api.datakeen.co/api/v1/reco/pay-slip \
     --header 'accept: application/json' \
     --header 'content-type: application/json'
npm install api --save

const sdk = require('api')('@datakeen/v1.4.0#ax268r1ilnd0liqe');

sdk.postRecoId()
  .then(({ data }) => console.log(data))
  .catch(err => console.error(err));
require 'uri'
require 'net/http'

url = URI("https://api.datakeen.co/api/v1/reco/pay-slip")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["accept"] = 'application/json'
request["content-type"] = 'application/json'

response = http.request(request)
puts response.read_body
composer require guzzlehttp/guzzle

<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.datakeen.co/api/v1/reco/pay-slip', [
  'headers' => [
    'accept' => 'application/json',
    'content-type' => 'application/json',
  ],
]);

echo $response->getBody();
python -m pip install requests

import requests

url = "https://api.datakeen.co/api/v1/reco/pay-slip"

headers = {
    "accept": "application/json",
    "content-type": "application/json"
}

response = requests.post(url, headers=headers)

print(response.text)
CURL *hnd = curl_easy_init();

curl_easy_setopt(hnd, CURLOPT_CUSTOMREQUEST, "POST");
curl_easy_setopt(hnd, CURLOPT_WRITEDATA, stdout);
curl_easy_setopt(hnd, CURLOPT_URL, "https://api.datakeen.co/api/v1/reco/pay-slip");

struct curl_slist *headers = NULL;
headers = curl_slist_append(headers, "accept: application/json");
headers = curl_slist_append(headers, "content-type: application/json");
curl_easy_setopt(hnd, CURLOPT_HTTPHEADER, headers);

CURLcode ret = curl_easy_perform(hnd);
dotnet add package RestSharp

using RestSharp;


var options = new RestClientOptions("https://api.datakeen.co/api/v1/reco/pay-slip");
var client = new RestClient(options);
var request = new RestRequest("");
request.AddHeader("accept", "application/json");
request.AddHeader("content-type", "application/json");
var response = await client.PostAsync(request);

Console.WriteLine("{0}", response.Content);

CURL *hnd = curl_easy_init();

curl_easy_setopt(hnd, CURLOPT_CUSTOMREQUEST, "POST");
curl_easy_setopt(hnd, CURLOPT_WRITEDATA, stdout);
curl_easy_setopt(hnd, CURLOPT_URL, "https://api.datakeen.co/api/v1/reco/pay-slip");

struct curl_slist *headers = NULL;
headers = curl_slist_append(headers, "accept: application/json");
headers = curl_slist_append(headers, "content-type: application/json");
curl_easy_setopt(hnd, CURLOPT_HTTPHEADER, headers);

CURLcode ret = curl_easy_perform(hnd);
(require '[clj-http.client :as client])

(client/post "https://api.datakeen.co/api/v1/reco/pay-slip" {:content-type :json
                                                       :accept :json})
package main

import (
	"fmt"
	"net/http"
	"io"
)

func main() {

	url := "https://api.datakeen.co/api/v1/reco/pay-slip"

	req, _ := http.NewRequest("POST", url, nil)

	req.Header.Add("accept", "application/json")
	req.Header.Add("content-type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(string(body))

}
POST /api/v1/reco/pay-slip HTTP/1.1
Accept: application/json
Content-Type: application/json
Host: api.datakeen.co
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://api.datakeen.co/api/v1/reco/pay-slip")
  .post(null)
  .addHeader("accept", "application/json")
  .addHeader("content-type", "application/json")
  .build();

Response response = client.newCall(request).execute();
const options = {
  method: 'POST',
  headers: {accept: 'application/json', 'content-type': 'application/json'}
};

fetch('https://api.datakeen.co/api/v1/reco/pay-slip', options)
  .then(response => response.json())
  .then(response => console.log(response))
  .catch(err => console.error(err));
val client = OkHttpClient()

val request = Request.Builder()
  .url("https://api.datakeen.co/api/v1/reco/pay-slip")
  .post(null)
  .addHeader("accept", "application/json")
  .addHeader("content-type", "application/json")
  .build()

val response = client.newCall(request).execute()
#import <Foundation/Foundation.h>

NSDictionary *headers = @{ @"accept": @"application/json",
                           @"content-type": @"application/json" };

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://api.datakeen.co/api/v1/reco/pay-slip"]
                                                       cachePolicy:NSURLRequestUseProtocolCachePolicy
                                                   timeoutInterval:10.0];
[request setHTTPMethod:@"POST"];
[request setAllHTTPHeaderFields:headers];

NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request
                                            completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
                                                if (error) {
                                                    NSLog(@"%@", error);
                                                } else {
                                                    NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;
                                                    NSLog(@"%@", httpResponse);
                                                }
                                            }];
[dataTask resume];
open Cohttp_lwt_unix
open Cohttp
open Lwt

let uri = Uri.of_string "https://api.datakeen.co/api/v1/reco/pay-slip" in
let headers = Header.add_list (Header.init ()) [
  ("accept", "application/json");
  ("content-type", "application/json");
] in

Client.call ~headers `POST uri
>>= fun (res, body_stream) ->
  (* Do stuff with the result *)
$headers=@{}
$headers.Add("accept", "application/json")
$headers.Add("content-type", "application/json")
$response = Invoke-WebRequest -Uri 'https://api.datakeen.co/api/v1/reco/pay-slip' -Method POST -Headers $headers
library(httr)

url <- "https://api.datakeen.co/api/v1/reco/pay-slip"

response <- VERB("POST", url, content_type("application/json"), accept("application/json"))

content(response, "text")
import Foundation

let headers = [
  "accept": "application/json",
  "content-type": "application/json"
]

let request = NSMutableURLRequest(url: NSURL(string: "https://api.datakeen.co/api/v1/reco/pay-slip")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()

🚧

Sending multiple documents

Scans, pictures and documents should be sent one by one. If you want to send multiple scans at the same time, please refer to the multi-docs API.

API Response

An instance of the usual response is displayed in the following JSON. You will find the complete information, including extraction and checks. More detailed examples of each extracted field are given below.

{
    "extractedInformation": {
        "SSCeiling": {
            "confidence": 0.8300130904503789,
            "value": "3428"
        },
        "address": {
            "confidence": 0.922897473518205,
            "value": "4 RUE DES OLIVES 94500 CHAMPIGNY SUR MARNE"
        },
        "apeCode": {
            "confidence": 0.8687543928726882,
            "value": "4332A"
        },
        "companyAddress": {
            "confidence": 0.9251000810295196,
            "value": "25 QUAI ANDRE CITROEN 75015 PARIS 15"
        },
        "companyName": {
            "confidence": 0.8750938821651175,
            "value": "K & M TRAVAUX"
        },
        "cp": {
            "confidence": 0.8742214801971926,
            "value": "12"
        },
        "grossSalary": {
            "confidence": 0.8697581773972907,
            "value": "3600"
        },
        "job": {
            "confidence": 0.6804943420827669,
            "value": " Commercial"
        },
        "joiningDate": {
            "confidence": 0.8940156614077281,
            "value": "04/08/2021"
        },
        "nSS": {
            "confidence": 0.8995632286254143,
            "value": "294129712722222"
        },
        "name": {
            "confidence": 0.9033116688569862,
            "value": "PAUL DUPOND"
        },
        "netBeforeTax": {
            "confidence": 0.9767789840698242,
            "value": "3955,37"
        },
        "netCumulTaxInc": {
            "confidence": 0.8241673367535363,
            "value": "3950,58"
        },
        "netToPay": {
            "confidence": 0.8647263607528579,
            "value": "3663,26"
        },
        "period": {
            "confidence": 0.9,
            "value": "01-2022"
        },
        "siret": {
            "confidence": 0.8924369180893805,
            "value": "83250936800011"
        },
        "taxableNetIncome": {
            "confidence": 0.8602992176165714,
            "value": "3950,58"
        }
    }
}

INSEE results

"inseeResults": {
  "message": "Success",
  "results": {
    "etablissement": {
      "activitePrincipaleRegistreMetiersEtablissement": "4334ZC",
      "adresse2Etablissement": {
        "codeCedex2Etablissement": null,
        "codeCommune2Etablissement": null,
        "codePaysEtranger2Etablissement": null,
        "codePostal2Etablissement": null,
        "complementAdresse2Etablissement": null,
        "distributionSpeciale2Etablissement": null,
        "indiceRepetition2Etablissement": null,
        "libelleCedex2Etablissement": null,
        "libelleCommune2Etablissement": null,
        "libelleCommuneEtranger2Etablissement": null,
        "libellePaysEtranger2Etablissement": null,
        "libelleVoie2Etablissement": null,
        "numeroVoie2Etablissement": null,
        "typeVoie2Etablissement": null
      },
      "adresseEtablissement": {
        "codeCedexEtablissement": null,
        "codeCommuneEtablissement": "75115",
        "codePaysEtrangerEtablissement": null,
        "codePostalEtablissement": "75015",
        "complementAdresseEtablissement": null,
        "distributionSpecialeEtablissement": null,
        "indiceRepetitionEtablissement": null,
        "libelleCedexEtablissement": null,
        "libelleCommuneEtablissement": "PARIS 15",
        "libelleCommuneEtrangerEtablissement": null,
        "libellePaysEtrangerEtablissement": null,
        "libelleVoieEtablissement": "ANDRE CITROEN",
        "numeroVoieEtablissement": "25",
        "typeVoieEtablissement": "QUAI"
      },
      "anneeEffectifsEtablissement": "2020",
      "dateCreationEtablissement": "2017-09-22",
      "dateDernierTraitementEtablissement": "2022-08-29T10:22:02",
      "etablissementSiege": true,
      "nic": "00011",
      "nombrePeriodesEtablissement": 2,
      "periodesEtablissement": [
        {
          "activitePrincipaleEtablissement": "43.32A",
          "caractereEmployeurEtablissement": "O",
          "changementActivitePrincipaleEtablissement": false,
          "changementCaractereEmployeurEtablissement": true,
          "changementDenominationUsuelleEtablissement": false,
          "changementEnseigneEtablissement": false,
          "changementEtatAdministratifEtablissement": false,
          "dateDebut": "2018-01-01",
          "dateFin": null,
          "denominationUsuelleEtablissement": null,
          "enseigne1Etablissement": "K&M TRAVAUX RENOVATION ET CONSTRUCTION",
          "enseigne2Etablissement": null,
          "enseigne3Etablissement": null,
          "etatAdministratifEtablissement": "A",
          "nomenclatureActivitePrincipaleEtablissement": "NAFRev2"
        },
        {
          "activitePrincipaleEtablissement": "43.32A",
          "caractereEmployeurEtablissement": "N",
          "changementActivitePrincipaleEtablissement": false,
          "changementCaractereEmployeurEtablissement": false,
          "changementDenominationUsuelleEtablissement": false,
          "changementEnseigneEtablissement": false,
          "changementEtatAdministratifEtablissement": false,
          "dateDebut": "2017-09-22",
          "dateFin": "2017-12-31",
          "denominationUsuelleEtablissement": null,
          "enseigne1Etablissement": "K&M TRAVAUX RENOVATION ET CONSTRUCTION",
          "enseigne2Etablissement": null,
          "enseigne3Etablissement": null,
          "etatAdministratifEtablissement": "A",
          "nomenclatureActivitePrincipaleEtablissement": "NAFRev2"
        }
      ],
      "siren": "832509368",
      "siret": "83250936800011",
      "statutDiffusionEtablissement": "O",
      "trancheEffectifsEtablissement": "01",
      "uniteLegale": {
        "activitePrincipaleUniteLegale": "43.32A",
        "anneeCategorieEntreprise": "2020",
        "anneeEffectifsUniteLegale": "2020",
        "caractereEmployeurUniteLegale": "O",
        "categorieEntreprise": "PME",
        "categorieJuridiqueUniteLegale": "5710",
        "dateCreationUniteLegale": "2017-09-22",
        "dateDernierTraitementUniteLegale": "2022-08-29T10:22:02",
        "denominationUniteLegale": "K&M",
        "denominationUsuelle1UniteLegale": null,
        "denominationUsuelle2UniteLegale": null,
        "denominationUsuelle3UniteLegale": null,
        "economieSocialeSolidaireUniteLegale": null,
        "etatAdministratifUniteLegale": "A",
        "identifiantAssociationUniteLegale": null,
        "nicSiegeUniteLegale": "00011",
        "nomUniteLegale": null,
        "nomUsageUniteLegale": null,
        "nomenclatureActivitePrincipaleUniteLegale": "NAFRev2",
        "prenom1UniteLegale": null,
        "prenom2UniteLegale": null,
        "prenom3UniteLegale": null,
        "prenom4UniteLegale": null,
        "prenomUsuelUniteLegale": null,
        "pseudonymeUniteLegale": null,
        "sexeUniteLegale": null,
        "sigleUniteLegale": null,
        "societeMissionUniteLegale": null,
        "statutDiffusionUniteLegale": "O",
        "trancheEffectifsUniteLegale": "01"
      }
    }
  },
  "status": 200
}

Extracted information format

For each field, the confidence value indicates the degree of certainty of the extraction with regard to the data on the payslip.

Social security ceiling for the month

The SSCeiling (key) on the payslip is returned as a string (value).

SSCeilingValue
valuestring
confidencenumber
"SSCeiling": {
  "confidence": 0.8300130904503789,
  "value": "3428"
}

Employee's address

The address (key) on the payslip is returned as a string (value).

addressValue
valuestring
confidencenumber
"address": {
  "confidence": 0.922897473518205,
  "value": "4 RUE DES OLIVES 94500 CHAMPIGNY SUR MARNE"
}

APE Code

The apeCode (key) on the payslip is returned as a string (value).

apeCodeValue
valuestring
confidencenumber
"apeCode": {
  "confidence": 0.8687543928726882,
  "value": "4332A"
}

Company address

The companyAddress (key) on the payslip is returned as a string (value).

companyAddressValue
valuestring
confidencenumber
"companyAddress": {
  "confidence": 0.9251000810295196,
  "value": "25 QUAI ANDRE CITROEN 75015 PARIS 15"
},

Company name

The companyName (key) on the payslip is returned as a string (value).

companyNameValue
valuestring
confidencenumber
"companyName": {
  "confidence": 0.8750938821651175,
  "value": "K & M TRAVAUX"
}

Paid leave balance

The cp (key) on the payslip is returned as a string (value).

cpValue
valuestring
confidencenumber
"cp": {
  "confidence": 0.8742214801971926,
  "value": "12"
}

Gross salary

The grossSalary (key) on the payslip is returned as a string (value).

grossSalaryValue
valuestring
confidencenumber
"grossSalary": {
  "confidence": 0.8697581773972907,
  "value": "3600"
}

Job / Position

The job or gender (key) on the payslip is returned as a string (value).

jobValue
valuestring
confidencenumber
"job": {
  "confidence": 0.6804943420827669,
  "value": " Commercial"
}

Start date

The joiningDate (key) on the payslip is returned as a string (value).

joiningDateValue
valuestring
confidencenumber
"joiningDate": {
  "confidence": 0.8940156614077281,
  "value": "04/08/2021"
}

Social security number

The nSS (key) on the payslip is returned as a string (value).

nSSValue
valuestring
confidencenumber
"nSS": {
  "confidence": 0.8995632286254143,
  "value": "294129712700222"
}

Employee's name

The name (key) on the payslip is returned as a string (value).

nameValue
valuestring
confidencenumber
"name": {
  "confidence": 0.9033116688569862,
  "value": "PAUL DUPOND"
}

Net before tax

The netBeforeTax (key)_on the payslip is returned as a string (value)_.

netBeforeTaxValue
valuestring
confidencenumber
"netBeforeTax": {
  "confidence": 0.9767789840698242,
  "value": "3955,37"
}

Cumulative taxable net income for the year

The netCumulTaxInc (key) on the payslip is returned as a string (value).

netCumulTaxIncValue
valuestring
confidencenumber
"netCumulTaxInc": {
  "confidence": 0.8241673367535363,
  "value": "3950,58"
}

Net payable

The netToPay (key) on the payslip is returned as a string (value).

netToPayValue
valuestring
confidencenumber
"netToPay": {
  "confidence": 0.8647263607528579,
  "value": "3663,26"
}

Period

The period (key) on the payslip is returned as a string (value).

periodValue
valuestring
confidencenumber
"period": {
  "confidence": 0.9,
  "value": "01-2022"
}

Company SIRET number

The siret (key) on the payslip is returned as a string (value).

siretValue
valuestring
confidencenumber
"siret": {
  "confidence": 0.8924369180893805,
  "value": "83250936800011"
},

Net taxable income

The taxableNetIncome (key) on the payslip is returned as a string (value).

siretValue
valuestring
confidencenumber
"taxableNetIncome": {
  "confidence": 0.8602992176165714,
  "value": "2950,58"
}

Controls

Additional information

🚧

Loaded scans must pass prerequisites

To provide a qualitative service and a comprehensive data capture, every picture, scan, or document sent to our API must comply with determined prerequisites which can be found on this page

❗️

API limitations

  • Maximum size : 5 MB
  • Maximum number of calls per minute : 10 calls

What’s Next

Ready to process payslips ? See our API Reference for detailed information