This feature is available with the Advanced license. Contact Support to enable this feature in your site or to ask questions about your license.
The API Data Set feature allows you to pull a data set from your Grant Lifecycle Manager (GLM) or Scholarship Lifecycle Manager (SLM) site into an external system, such as a CRM or accounting system. The API enables data from that data set to automatically update in your external system based on the information in your site. For example, this could be used to display information about recent grantees on your foundation's website with that information automatically updating according to the data in your GLM site.
User Role: Administrator
How to Use API Data Sets:
- Automatically import grant or scholarship data from GLM/SLM into external systems like CRMs, accounting software, or databases.
- Display current grantee information on your organization's website that updates automatically based on GLM/SLM data.
- Connect GLM/SLM data to business intelligence or reporting tools for advanced analysis.
- Import GLM/SLM data into custom applications or internal systems that need real-time access to request and award information.
- Eliminate manual exports and imports using API Data Sets.
Create an API Data Set in GLM/SLM
To create an API data set, build a new data set or copy an existing one, enable the API option, configure the pre-filters and data fields, and generate API keys for external system access.
- Click Reporting on the upper navigation bar, and then click Reports & Data Sets.
- Click Add Data Set.
- An existing data set can also be copied to create an API Data Set. When copying an existing data set, check the Make this an API Data Set box.
- An existing data set can also be copied to create an API Data Set. When copying an existing data set, check the Make this an API Data Set box.
- Enter the applicable Data Set Create information, and then check the Make this an API Data Set box.
- Click Create Data Set.
- Select the pre-filters and data fields.
- Build a Data Set provides more information on selecting pre-filters and data fields.
- Because the data set is connected via the API, it cannot have any further modifications such as filters and formulas in GLM/SLM.
- Click Save.
- Click Reports.
- Click the API Data Sets tab.
- The data set that was saved will be listed in this tab.
- As with a regular data set, from here it can be edited, deleted, copied, or exported to Excel.
- The data set that was saved will be listed in this tab.
- Click the key icon to view the API keys for the data set.
- In the pop-up that appears, any existing API keys for the data set, who generated each key, and the option to revoke a key are available. Click Create New API Key to generate a new key for the data set.
- The new key ID (a random public GUID) and a cryptographically secure 32 byte secret value will be provided. Save these in a secure location. The secret value is only provided once.
- The key ID and secret value can then be added to the external system to finish setting up the API.
Details of an API Request
Time-bound HMAC SHA-256 signatures are used on all API requests with this feature to verify that only the owner of the API key secret is able to pull the data. This is accomplished by including a time stamp, the API key ID, and the HMAC signature of the request body with every request to the API. A new signature will need to be generated for each API request.
Request Headers
Method: POST
ContentType: application/json
ContentLength: Length of the body of the request
GLM-API-Key: The public key Id of your API key
GLM-API-Signature: The HMAC-SHA256 signature of the body of the request
Request Body
UTF-8 encoded json containing the actual request being made to the API. For now, this is just a UTC timestamp. For example: { "timestamp": 1519858633553 }
Code Sample (C#)
var apiKey = "[ENTER API KEY ID HERE]";
var secret = "[ENTER API SECRET HERE]";
// Convert the Hexadecimal secret value into its actual bytes
int length = secret.Length;
byte[] secretBytes = new byte[length / 2];
for (int c = 0; c < length; c += 2) {
secretBytes[c / 2] = Convert.ToByte(secret.Substring(c, 2), 16);
}
// Calculate the current UTC Timestamp (seconds since midnight on January 1, 1970)
var now = DateTime.UtcNow;
var timestamp = (int)now.Subtract(new DateTime(1970, 1, 1)).TotalSeconds;
var json = $"{{\"timestamp\":{timestamp}}}";
// Compute the HMAC SHA-256 signature of the json request body
var hmac256 = new System.Security.Cryptography.HMACSHA256(secretBytes);
var hash = hmac256.ComputeHash(Encoding.ASCII.GetBytes(json));
var signature = BitConverter.ToString(hash).Replace("-","");
// Construct the request we will send to the API
WebRequest request = WebRequest.Create("https://www.grantinterface.com/API/DataSet/GetData");
request.Headers["GLM-API-Key"] = apiKey;
request.Headers["GLM-API-Signature"] = signature;
UTF8Encoding encoding = new UTF8Encoding();
byte[] body = encoding.GetBytes(json);
request.Method = "POST";
request.ContentType = "application/json";
request.ContentLength = body.Length;
request.GetRequestStream().Write(body, 0, body.Length);
try {
string csvData;
// Send the request and
var response = request.GetResponse();
using (StreamReader reader = new StreamReader(response.GetResponseStream())) {
// Read the response data
csvData = reader.ReadToEnd();
}
// ...
// Process the data here
// ...
} catch (WebException e) {
// Handle errors
}Code Sample (Python)
#!/usr/bin/python3
import httplib2
import hashlib
import hmac
import time
key = '[ENTER API KEY ID HERE]'
secret = '[ENTER API SECRET HERE]'
url = 'https://www.grantinterface.com/API/DataSet/GetData'
unixtime = time.time()
body = '{"timestamp":' + str(unixtime) + '}'
secretBytes = bytearray.fromhex(secret)
bodyBytes = bytearray(body, "utf8")
signature = hmac.new(secretBytes, bodyBytes, digestmod=hashlib.sha256).hexdigest()
headers = {
'Content-type': 'application/json',
'GLM-API-Key': key,
'GLM-API-Signature': signature
}
http = httplib2.Http()
response, content = http.request(url, 'POST', headers=headers, body=body)
if response.status == 200:
print(content)
else:
print(response.reason)Code Sample (Javascript)
var apiKey = "ADD API KEY HERE";
var secret = "ADD SECRET HERE";
var time = Math.round((new Date()).getTime() / 1000);
var body = "{\"timestamp\":" + time+ "}";
var bodyBytes = CryptoJS.enc.Utf8.parse(body);
var secretBytes = CryptoJS.enc.Hex.parse(secret);
var signature = CryptoJS.HmacSHA256(bodyBytes, secretBytes);
var signatureString = signature.toString(CryptoJS.enc.Hex);
pm.environment.set("glm_api_key", apiKey);
pm.environment.set("glm_api_signature", signatureString);
pm.request.body = body;
Code Sample (R)
require(httr)
require(jsonlite)
require(digest)
require(openssl)
key <- "API_KEY"
secret <- "API_SECRET"
url <- "https://www.grantinterface.com/API/DataSet/GetData"
(unixtime <- as.numeric(Sys.time()))
(body <- toJSON(list(timestamp = unixtime), auto_unbox = TRUE))
#body <- '{"timestamp":1712337415.081513}'
# Split the secret into a vector of two-character strings
split_secret <- strsplit(tolower(secret), split = "(?<=\\G..)", perl = TRUE)[[1]]
# Convert each two-character string from hex to raw bytes
secretBytes <- do.call(c, lapply(split_secret, function(x) as.raw(strtoi(x, 16L))))
# Convert the body to a raw byte array
bodyBytes <- charToRaw(body)
print(bodyBytes)
# Generate the HMAC signature
signature <- hmac(secretBytes, bodyBytes, algo = "sha256", raw = FALSE)
# Print the signature
print(signature)
headers <- add_headers(
'Content-type' = 'application/json',
'GLM-API-Key' = key,
'GLM-API-Signature' = signature
)
response <- POST(url, body = body, headers)
if (http_status(response)$category == "Success") {
print(content(response, as = "text"))
} else {
print(http_status(response)$message)
}