Skip to end of metadata
Go to start of metadata


You can use the Attendance Swipe API to upload the recorded attendance swipe data to greytHR. To use this API, you must first generate the API key and use this key to authenticate yourself as a valid user while calling the API.

 API Key Generation

greytHR provides the Attendance Swipe API that you can integrate with your business apps to send attendance data. To use the greytHR API's, you need to first generate the API keys. API key is a secret key which must be passed to the greytHR application while calling the API. 


The API feature is available only to SUPER and CRUISER plan users.

To generate the API key for Attendance Swipe API:

  1. Navigate to My Account > API Details.
  2. In the API Keys section,click the 
  3. To generate API key for the Attendance Swipe API, select the option Attendance Swipe API Key.
  4. Click Generate API Keys.

  5. Click Done.
    Domain URL refers to the URL that is used by the customer to access the greytHR application. The API Name refers to the unique name associated with the API and is editable. API ID is the unique API key which is displayed only once.
    i. Click Download Private Key to generate the PEM (Privacy Enhanced Mail) which is the certificate or encoded file.


For the Attendance Swipe API, you can generate multiple API keys.

Delete / Regenerate API Key

Once an API key is created, you can either delete it or regenerate it.

  1. Click  to delete the API key.
  2. Click Regenerate to regenerate the API key. The API key is regenerated with all references to the previous key removed.
  3. Click Regenerate to confirm.


Please do not share the following info:

Access ID: Unqiue ID generated for every customer. Will remain the same for both Attendance and Employee APIs.

API Key: Unique key for API Access

API ID: Unique API ID for the Attendance API

API Name: Custom field given to set the name/ identifier for the Attendance API

PEM: Certificate / Encoded file

Domain URL: URL which is the same as your login URL

 Upload Recorded Swipes

After generating the API key as discussed above, use this key to push the attendance swipes data to greytHR.


A minimum of 10 seconds gap must be maintained between two uploads.


https://<domain name>







IDThis is the API ID generated in the API Details page.

It is a list of line separated swipes, where each swipe entry has the
below format:

<date-time in ISO format>,<employee-code>,<door-name>,<1(in)/0(out)>

For example,
● 2017-03-10T13:46:58.260+05:30,658,Main Door,1 (indicating an in-swipe)

● 2017-03-10T13:46:58.260+05:30,658,Main Door,0 (indicating an out-swipe)
SignSHA1 with RSA signature of the swipes string (Base64 encoded).
 Attendance Swipes Verification

To verify that the swipes are successfully recorded in greytHR, perform the following steps:

  1. Navigate to Leave > Information > Employee Swipe
  2. In the Employee Swipes tab, select the Date Type filter as Received On.
  3. Date represents the current date. To check for swipes pushed on a particular date, select from the Date filter drop down.
  4. Select the Type filter as All.


If there are no records, it means that the swipes are not pushed to greytHR.

 Sample Code Java
package com.greytip.cougar.asca.api.runner;

import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.codec.binary.Base64;
import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

public class TestAPIUpload {

    public static void main(String[] args) throws InvalidKeyException, NoSuchAlgorithmException, SignatureException,
            InvalidKeySpecException, IOException {

    private static void upload() throws IOException, InvalidKeyException, NoSuchAlgorithmException, SignatureException,
            InvalidKeySpecException {

        String baseUrl = ""; // use the url to upload swipes

        String id = "54af45e7-5016-4111-848a-0f8b205d2222"; // replace with actual id sent by greytip

        String privateKeyFile = "D:\\HRIS\\54af45e7-5016-4111-848a-0f8b205d2222.pem"; // copy the pem file in this path

        String swipes = "2018-01-03T09:30:30.654+05:30,5018,Main Door,1\r\n2018-01-03T18:00:25.654+05:30,5018,Main Door,0";  //sample swipes
        /* create swipes.txt file like below or use the above swipes format to upload
         * 2018-01-03T09:30:30.654+05:30,5018,Main Door,1
         * 2018-01-03T18:00:25.654+05:30,5018,Main Door,0

        /*String swipesPath = "D:\\logs\\swipes.txt";
        String swipes = FileUtils.readFileToString(new File(swipesPath), Charset.defaultCharset());*/        

        try (CloseableHttpClient httpclient = HttpClients.custom().build()) {
            HttpPost httpost = new HttpPost(baseUrl + "/v2/attendance/asca/swipes");
            httpost.setHeader("X-Requested-With", "XMLHttpRequest");

            String sign = signRSA(swipes, createRSAPrivateKey(
                    FileUtils.readFileToString(new File(privateKeyFile), Charset.defaultCharset())));

            List<NameValuePair> nvps2 = new ArrayList<NameValuePair>();
            nvps2.add(new BasicNameValuePair("id", id));
            nvps2.add(new BasicNameValuePair("swipes", swipes));
            nvps2.add(new BasicNameValuePair("sign", sign));

            httpost.setEntity(new UrlEncodedFormEntity(nvps2, Consts.UTF_8));

            HttpResponse response = httpclient.execute(httpost);
            HttpEntity entity = response.getEntity();
            String responseText = EntityUtils.toString(entity);
            if (response.getStatusLine().getStatusCode() != org.apache.http.HttpStatus.SC_OK) {
                throw new RuntimeException("Server responded with error code: "
                        + response.getStatusLine().getStatusCode() + " and content: [" + responseText + "]");

    private static String signRSA(String string, PrivateKey privateKey)
            throws NoSuchAlgorithmException, InvalidKeyException, SignatureException {
        Signature dsa = Signature.getInstance("SHA1withRSA");

        byte[] bytes = string.getBytes();
        dsa.update(bytes, 0, bytes.length);
        byte[] signature = dsa.sign();

        return Base64.encodeBase64String(signature);

    private static PrivateKey createRSAPrivateKey(String string)
            throws InvalidKeySpecException, NoSuchAlgorithmException, IOException {
        PemObject pemObject;
        try (PemReader reader = new PemReader(new StringReader(string));) {
            pemObject = reader.readPemObject();

        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(pemObject.getContent());
        return KeyFactory.getInstance("RSA").generatePrivate(keySpec);
 Sample Code C#

using System;

using System.IO;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;


using Org.BouncyCastle.Utilities;

using Org.BouncyCastle.OpenSsl;

using Org.BouncyCastle.Crypto;

using Org.BouncyCastle.Crypto.Parameters;

using Org.BouncyCastle.Security;

using RestSharp;


namespace ConsoleApp1


    class Program


        static void Main(string[] args)


            DateTime dt = DateTime.Now;




            String domainName = "<domain-name>";

            String keyString = @"-----BEGIN PRIVATE KEY-----

//private key

-----END PRIVATE KEY-----";



            String swipes = "2017-04-03T13:41:30.654+05:30,5018,Main Door,1\r\n2017-04-03T13:41:25.654+05:30,5018,Main Door,1";


            String sign = Sign(swipes, keyString);



            RestClient client = new RestClient("https://" + domainName);


            RestRequest request = new RestRequest("/v2/attendance/asca/swipes", Method.POST);

            request.AddParameter("swipes", swipes);

            request.AddParameter("sign", sign);

            request.AddParameter("id", "68733a17-c8d1-4010-bc2e-3b5c06f82d7f");


            IRestResponse response = client.Execute(request);







        static RsaPrivateCrtKeyParameters readPrivateKey(string privateKeyFileName)


            RsaPrivateCrtKeyParameters keyPair;


            using (var reader = File.OpenText(privateKeyFileName))

                keyPair = (RsaPrivateCrtKeyParameters)new PemReader(reader).ReadObject();


            return keyPair;



        static RsaPrivateCrtKeyParameters getPrivateKey(String keyString)


            RsaPrivateCrtKeyParameters keyPair;

            using (var reader = new StringReader(keyString))

                keyPair = (RsaPrivateCrtKeyParameters)new PemReader(reader).ReadObject();


            return keyPair;




        static public String Sign(String data, String keyString)


            RsaKeyParameters key = getPrivateKey(keyString);


            ISigner sig = SignerUtilities.GetSigner("SHA1withRSA");

            sig.Init(true, key);

            var bytes = Encoding.UTF8.GetBytes(data);

            sig.BlockUpdate(bytes, 0, bytes.Length);

            byte[] signature = sig.GenerateSignature();


            var signedString = Convert.ToBase64String(signature);

            return signedString;





 Sample Code Node JS

const crypto = require('crypto');
const sign = crypto.createSign('RSA-SHA1');
const fs = require('fs')
const querystring = require('querystring');
const https = require('https');

const host = '<domain name>';//Your greytHR account domain example ''
const id = "4d433194-e00e-469e-b95f-00685cd480ec";//API ID generated from greytHR in API details page
const privateKey = fs.readFileSync('attendance/key.pem');//Private key generated from greytHR in API Details page
const swipes = fs.readFileSync('attendance/swipes.txt').toString();//Batch of swipes, one swipe per line

// use like below format for private key & swipes also
const privateKey = '-----BEGIN PRIVATE KEY-----
    PRIVATE KEY generated from greytHR in API Details page content to be copied Here
-----END PRIVATE KEY-----';
const swipes = '2018-02-10T09:46:58.260+05:30,658,Main Door,1\r\n2018-02-10T18:46:58.260+05:30,658,Main Door,0'; //your swipes in the given format


const signature = sign.sign(privateKey, 'base64');

const postData = querystring.stringify({
    "id": id,
    "swipes": swipes,
    "sign": signature

const options = {
    hostname: host,
    path: '/v2/attendance/asca/swipes',
    method: 'POST',
    headers: {
        'Content-Type': 'application/x-www-form-urlencoded',
        'Content-Length': Buffer.byteLength(postData),
        "X-Requested-With": "XMLHttpRequest"

const req = https.request(options, (res) => {
    console.log(`STATUS: ${res.statusCode}`);
    if (res.statusCode === 200) {
    } else {
        console.log(`HEADERS: ${JSON.stringify(res.headers)}`);
        res.on('data', (chunk) => {

req.on('error', (e) => {
    console.error(`problem with request: ${e.message}`);

// write data to request body

 Sample Code PHP

    $id = "<agent-id>";//API ID generated from greytHR in API details page
    $swipes = file_get_contents('file:///attendance/swipes.txt');//Batch of swipes, one swipe per line
    $pkeyid = openssl_pkey_get_private("file:///attendance/private-key.pem");//Private Key generated from greytHR in API details page

    openssl_sign($swipes, $signature, $pkeyid, OPENSSL_ALGO_SHA1);

    $data = array(
        "id" => $id,
        "swipes" => $swipes,
        "sign" => base64_encode($signature)

    $curl = curl_init();
    curl_setopt_array($curl, array(
        CURLOPT_URL => "https://<domain-name>/v2/attendance/asca/swipes",
        CURLOPT_HEADER => true,
        CURLOPT_POST => true,
        CURLOPT_POSTFIELDS => $data,
        CURLOPT_HTTPHEADER => array(
            "X-Requested-With: XMLHttpRequest"
    $response = curl_exec($curl);
    //Need to test for status 200(Ok) to make sure the request was successful
    $err = curl_error($curl);

  • No labels