Updated inย March- 2024 |ย Subscribe to watch greytHR how-to video
Generating an API key for the attendance swipe API refers to the process of creating a unique identifier that allows authorized applications or systems to securely access and utilize the attendance swipe API functionality.
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.
greytHR provides the Attendance Swipe API that you can integrate with your business apps to send attendance data. To use the greytHR APIs, you need to first generate the API keys from the API Details page. An API key is a secret key that must be passed to the greytHR application while calling the API.
To view the API Details page, click the Settings icon > My Account > API Details.
You can perform the following actions on the API Details page:
Generate API key for Attendance Swipe API.
Delete/regenerate API key.
To generate the API key for attendance swipe API, perform the following actions:
On the API Details page, in the API Keys section, click the + icon. The pop-up appears.
On the pop-up, select Attendance Swipe API Key option.
Click Generate API Keys button. The Attendance Swipe API Key pop-up appears. The Domain URL, API Name, and API ID details auto-populates.
Domain URL refers to the URL that the customer uses to access the greytHR application.
The API Name refers to the unique name associated with the API and is editable.
The API ID is the unique API key which is displayed only once.
Click Download Private Key to generate the PEM (Privacy Enhanced Mail) which is the certificate or encoded file.
Click Done to generate the API key for attendance swipe API.
Note:ย
The API feature is available only to Growth and Enterprise plan users.
For the Attendance Swipe API, you can generate multiple API keys.
Once an API key is created, you can either delete it or regenerate it. To delete/regenerate the API key, perform the following actions:
On the API Details page, the list of generated API keys appears.
Select the required API key and click the Delete icon to delete that API key.
Click the Regenerate button. The Regenerate API Key pop-up appears.
Click the Regenerate button. The Employee and Salary API Key pop-up appears.
Click Done to regenerate the API key.
Note: Please do not share the following info:
Access ID: Unique ID generated for every customer. It 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.
Once you generate 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>.greythr.com/v2/attendance/asca/swipes
POST
X-Requested-With=XMLHttpRequest
IID - This is the API ID generated on the API Details page.
Swipes - 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)
Sign - SHA1 with RSA signature of the swipes string (Base64 encoded).
To verify that the swipes are successfully recorded in greytHR, perform the following actions:
From your greytHR Admin login, navigate to Leave > Information > Employee Swipe.
From the Date Type dropdown filter, select the Received On option.
From the Select Dates dropdown calendar, select the required dates.ย
In the Employee Search search box, search for the employee whose swipes you want to verify. The list of selected employee swipes appears.
Note: If there are no records, it means that the swipes are not pushed to greytHR.
package com.greytip.cougar.asca.api.runner;
import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.nio.charset.Charset;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.Signature;
import java.security.SignatureException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.FileUtils;
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;
import org.bouncycastle.util.io.pem.PemObject;
import org.bouncycastle.util.io.pem.PemReader;
public class TestAPIUpload {
public static void main(String[] args) throws InvalidKeyException, NoSuchAlgorithmException, SignatureException,
InvalidKeySpecException, IOException {
upload();
}
private static void upload() throws IOException, InvalidKeyException, NoSuchAlgorithmException, SignatureException,
InvalidKeySpecException {
String baseUrl = "https://abcxyz.greythr.com"; // 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");
dsa.initSign(privateKey);
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);
}
}
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;
System.Console.WriteLine(dt.ToString("yyyy-MM-ddTHH:mm:ss.fffzzz"));
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);
//System.Console.WriteLine(sign);
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);
System.Console.WriteLine(response.ResponseStatus);
System.Console.WriteLine(response.Content);
}
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;
}
}
}
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 'test.greytip.in'
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
*/
sign.write(swipes);
sign.end();
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) {
console.log('successful')
} else {
console.log('failed')
console.log(`HEADERS: ${JSON.stringify(res.headers)}`);
res.on('data', (chunk) => {
console.log(JSON.parse(chunk));
});
}
});
req.on('error', (e) => {
console.error(`problem with request: ${e.message}`);
});
// write data to request body
req.write(postData);
req.end();
<?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
$private_key = file_get_contents("file:///attendance/private-key.pem");
$pkeyid = openssl_pkey_get_private($private_key);//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_RETURNTRANSFER => true,
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);
print_r($response);
print_r($err);
curl_close($curl);
die();
?>
from Crypto.Signature import PKCS1_v1_5
from Crypto.Hash import SHA
from Crypto.PublicKey import RSA
import base64
import http.client
import urllib
gthost = 'abcd.greythr.com'; #greytHR Base URL
gtapiid='xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx'; #Replace with actual API ID
Attendpoint = '/v2/attendance/asca/swipes'; #End point URL to upload swipes
swipes = '2020-04-15T09:30:30.654+05:30,5018,Main Door,1\r\n2020-04-15T18:00:25.654+05:30,5018,Main Door,0' #sample swipes format
'''
We can read swipes data from csv file Or from any Database. The Format as given below
2020-04-15T09:30:30.654+05:30,5018,Main Door,1
2020-04-15T18:00:25.654+05:30,5018,Main Door,0
'''
key = RSA.importKey(open('Private.pem').read()) #Attendance Private Key generated from greytHR
h = SHA.new(bytes(swipes,"ascii"))
signer = PKCS1_v1_5.new(key)
signature = signer.sign(h)
gtsign=base64.b64encode(signature).decode() # Decode Signature to String
print("signature:"+gtsign) # If need to veiry the Signature
swipes=urllib.parse.quote(swipes) #URLEncode Swipes
gtsign=urllib.parse.quote(gtsign) #URLEncode Signature
conn = http.client.HTTPSConnection(gthost)
url = "https://"+gthost+Attendpoint
payload = 'id='+gtapiid+'&swipes='+swipes+'&sign='+gtsign
headers = {'X-Requested-With': 'XMLHttpRequest',
'Content-Type': 'application/x-www-form-urlencoded'}
conn.request("POST",Attendpoint, payload, headers) #Push the attendance swipes data to greytHR
res = conn.getresponse()
data = res.read()
Response= data.decode("utf-8")
if Response !='':
print("Server responded with error:"+ data.decode("utf-8"))
else :
print("Swipes uploaded successfully")
Other related links:
โถ Video - Watch our how-to videos to learn more about greytHR.
โ FAQs - Solve your queries using FAQs.
๐ข Product Update - Read about the product updates.