# install curl
npm install accessgrid
bundle add accessgrid
pip install accessgrid
go get accessgrid
Install-Package accessgrid.dll -Version 1.0.0
implementation "com.accessgrid.sdk:accessgrid:1.0.0"
composer require accessgrid/accessgrid
Authentication
We use a dual authentication mechanism, it consists of two parts:
- A static account id to be sent in the X-ACCT-ID header
- A shared secret scheme to authenticate every API request with a signed payload in the X-PAYLOAD-SIG header
You can find both keys in your AccessGrid console on the API keys page. If you're logged in, they're automatically embedded into this documentation.
List Access Passes
Retrieve a paginated list of Access Passes. Optionally provide a template_id to list passes for a specific card template, or omit it to list all passes across all templates in your account. You can also filter by current state.
template_id
nullable string
Optional. The card template ID to list keys for. If omitted, returns keys for all templates in the account.
state
nullable string
Filter keys by state (active, suspended, unlink, deleted)
page
nullable integer
Page number for pagination (default: 1)
per_page
nullable integer
Number of results per page (default: 25, max: 100)
Request
# Prepare for GET request
# Create a payload with the template ID
TEMPLATE_ID="0xd3adb00b5"
PAYLOAD='{"id":"$TEMPLATE_ID"}'
PAYLOAD_B64=$(echo -n $PAYLOAD | base64)
HASH=$(echo -n "$SHARED_SECRET$PAYLOAD_B64" | openssl sha256 | awk '{print $2}')
# Send curl request
curl -v \
-X GET \
-H 'X-ACCT-ID: 123' \
-H "X-PAYLOAD-SIG: $HASH" \
"https://api.accessgrid.com/v1/key-cards?template_id=$TEMPLATE_ID&sig_payload=" + urlencode($PAYLOAD)
require('accessgrid')
acct_id = ENV['ACCOUNT_ID']
secret_key = ENV['SECRET_KEY']
client = AccessGrid.new(acct_id, secret_key)
# Get filtered keys by template
keys = client.access_cards.list(template_id: "0xd3adb00b5")
# Get filtered keys by state
keys = client.access_cards.list(state: "active")
# Print keys
keys.each do |key|
puts "Key ID: #{key.id}, Name: #{key.full_name}, State: #{key.state}"
end
import AccessGrid from 'accessgrid';
const accountId = process.env.ACCOUNT_ID;
const secretKey = process.env.SECRET_KEY;
const client = new AccessGrid(accountId, secretKey);
const listKeys = async () => {
try {
// Get filtered keys by template
const templateKeys = await client.accessCards.list({ templateId: "0xd3adb00b5" });
// Get filtered keys by state
const activeKeys = await client.accessCards.list({ state: "active" });
// Print keys
allKeys.forEach(key => {
console.log(`Key ID: ${key.id}, Name: ${key.fullName}, State: ${key.state}`);
});
} catch (error) {
console.error('Error listing Access Passes:', error);
}
};
listKeys();
from accessgrid import AccessGrid
import os
account_id = os.getenv('ACCOUNT_ID')
secret_key = os.getenv('SECRET_KEY')
client = AccessGrid(account_id, secret_key)
# Get filtered keys by template
template_keys = client.access_cards.list(template_id="0xd3adb00b5")
# Get filtered keys by state
active_keys = client.access_cards.list(state="active")
# Print keys
for key in all_keys:
print(f"Key ID: {key.id}, Name: {key.full_name}, State: {key.state}")
package main
import (
"fmt"
"os"
"github.com/accessgrid/accessgrid-go"
)
func main() {
accountID := os.Getenv("ACCOUNT_ID")
secretKey := os.Getenv("SECRET_KEY")
client, err := accessgrid.NewClient(accountID, secretKey)
if err != nil {
fmt.Printf("Error creating client: %v\n", err)
return
}
// Get filtered keys by template
templateFilter := accessgrid.ListKeysParams{
TemplateID: "0xd3adb00b5",
}
templateKeys, err := client.AccessCards.List(&templateFilter)
if err != nil {
fmt.Printf("Error listing cards: %v\n", err)
return
}
// Get filtered keys by state
stateFilter := accessgrid.ListKeysParams{
State: "active",
}
activeKeys, err := client.AccessCards.List(&stateFilter)
if err != nil {
fmt.Printf("Error listing cards: %v\n", err)
return
}
// Print keys
for _, key := range allKeys {
fmt.Printf("Key ID: %s, Name: %s, State: %s\n", key.ID, key.FullName, key.State)
}
}
using AccessGrid;
using System;
using System.Threading.Tasks;
public async Task ListCardsAsync()
{
var accountId = Environment.GetEnvironmentVariable("ACCOUNT_ID");
var secretKey = Environment.GetEnvironmentVariable("SECRET_KEY");
var client = new AccessGridClient(accountId, secretKey);
// Get filtered keys by template
var templateKeys = await client.AccessCards.ListAsync(new ListKeysRequest
{
TemplateId = "0xd3adb00b5"
});
// Get filtered keys by state
var activeKeys = await client.AccessCards.ListAsync(new ListKeysRequest
{
State = "active"
});
// Print keys
foreach (var key in allKeys)
{
Console.WriteLine($"Key ID: {key.Id}, Name: {key.FullName}, State: {key.State}");
}
}
public class ListKeysRequest
{
public string TemplateId { get; set; }
public string State { get; set; }
}
import com.organization.accessgrid.AccessGridClient;
import com.organization.accessgrid.model.Card;
import com.organization.accessgrid.model.ListKeysParams;
import java.util.List;
public class AccessCardService {
private final AccessGridClient client;
public AccessCardService() {
String accountId = System.getenv("ACCOUNT_ID");
String secretKey = System.getenv("SECRET_KEY");
this.client = new AccessGridClient(accountId, secretKey);
}
public void listCards() throws AccessGridException {
// Get filtered keys by template
ListKeysParams templateFilter = ListKeysParams.builder()
.templateId("0xd3adb00b5")
.build();
List<Card> templateKeys = client.accessCards().list(templateFilter);
// Get filtered keys by state
ListKeysParams stateFilter = ListKeysParams.builder()
.state("active")
.build();
List<Card> activeKeys = client.accessCards().list(stateFilter);
// Print keys
for (Card key : allKeys) {
System.out.printf("Key ID: %s, Name: %s, State: %s%n",
key.getId(),
key.getFullName(),
key.getState());
}
}
}
Response
{
"status": "success",
"count": 2,
"total_count": 2,
"page": 1,
"per_page": 20,
"total_pages": 1,
"keys": [
{
"id": "key_9f3a12bc",
"full_name": "John Doe",
"employee_id": "EMP-10234",
"state": "active",
"install_url": "https://install.accessgrid.io/pass/key_9f3a12bc",
"card_template_id": "0xd3adb00b5",
"expiration_date": "2026-03-31T23:59:59Z",
"created_at": "2025-01-15T10:22:11Z",
"metadata": {
"department": "Engineering",
"location": "HQ"
},
"card_number": "4920-8833-1122",
"site_code": "NYC-HQ",
"direct_install_url": "https://pay.google.com/gp/v/save/abcdef123456"
},
{
"id": "key_b81d77ef",
"full_name": "Jane Smith",
"employee_id": "EMP-10891",
"state": "inactive",
"install_url": "https://install.accessgrid.io/pass/key_b81d77ef",
"card_template_id": "0xhotel98765",
"expiration_date": "2025-12-31T23:59:59Z",
"created_at": "2024-11-03T08:45:00Z",
"metadata": {
"department": "Operations",
"role": "Manager"
},
"file_data": {
"file_name": "hotel_pass.pkpass",
"file_size": 24576
},
"is_pass_ready_to_transact": true
}
]
}
Issue Access Pass
Enable a pass to be added to be created and installed on their mobile device with the constraints set in the AccessGrid console and this API call. Returns a landing page for installing the access pass.
card_template_id
string
Unique identifier for the card template to use
employee_id
string
Unique identifier for the employee
tag_id
nullable string
Tag identifier associated with the Access Pass, only allowed if your card template has key diversification enabled. Must be 7 bytes, 14 chars, ex: DF517FC87144DF
site_code
nullable string
Site code from H10301 (26 bit) format. Must be number under 255. Required if `file_data` not present.
card_number
string
Site code from H10301 (26 bit) format. Must be number under 65,535
file_data
nullable string
Up to 64 characters of hexadecimal data (0-9, A-F). Only used when implementing proprietary data formats.
full_name
string
Full name of the Access Pass owner
nullable string
Email address of the Access Pass owner - if you have a SendGrid or Postmark integration, then we will send a text message on your behalf
phone_number
nullable string
Contact phone number for the Access Pass owner - if you have a Twilio integration, then we will send a text message on your behalf
classification
string
Employment classification (e.g., full_time, contractor)
start_date
string
ISO8601 timestamp when the key card becomes active
expiration_date
string
ISO8601 timestamp when the key card expires
employee_photo
string
Base64 encoded PNG image of the employee (max 10MB)
title
nullable string
Job title or department of the employee
member_id
nullable string
Only for 'hotel' use case. Loyalty/membership ID of the guest
membership_status
nullable string
Only for 'hotel' use case. Status of the guest's membership
is_pass_ready_to_transact
nullable boolean
Only for 'hotel' use case. Whether the pass is ready to be used for NFC transactions
tile_data
nullable object
Only for 'hotel' use case. Data for the hotel tile display
checkInAvailableWindowStartDateTime
nullable string
ISO8601 timestamp with timezone. Required if isCheckedIn is missing or false
checkInAvailableWindowEndDateTime
nullable string
ISO8601 timestamp with timezone. Required if isCheckedIn is missing or false
checkInDateTime
nullable string
ISO8601 timestamp with timezone. Required if isCheckedIn is true
checkInURL
nullable string
URL for remote check-in. Only used if isCheckedIn is missing or false
isCheckedIn
nullable boolean
Whether the guest has checked in
numberOfRoomsReserved
nullable integer
Number of rooms reserved. Must match the number of roomNumbers if both are present
roomNumbers
nullable array
Array of room numbers. Must match the number of numberOfRoomsReserved if both are present
reservations
nullable object
Only for 'hotel' use case. Data for the hotel reservation
checkInDateTime
nullable string
ISO8601 timestamp with timezone. Required if isCheckedIn is true
isCheckedIn
nullable boolean
Whether the guest has checked in
numberOfRoomsReserved
nullable integer
Number of rooms reserved. Must match the number of roomNumbers if both are present
propertyLocation
nullable string
Location of the property (e.g., 'Key West')
propertyName
nullable string
Name of the property (e.g., 'Hyatt Centric Resort & Spa')
propertyMapUrl
nullable string
URL to a map of the property
propertyCategory
nullable string
Category of the property. If provided, must be 'travel'
restaurantVoucher
nullable string
Optional voucher for restaurant services
reservationEndDateTime
nullable string
ISO8601 timestamp with timezone for reservation end
reservationNumber
nullable string
Confirmation number for the reservation
reservationStartDateTime
nullable string
ISO8601 timestamp with timezone for reservation start
roomNumbers
nullable array
Array of room numbers. Must match the number of numberOfRoomsReserved if both are present
metadata
nullable object
Custom JSON object for storing additional metadata associated with the access pass. Can contain any valid JSON data.
credential_pool_id
nullable string
Optional credential pool ID to use for automatic credential assignment. When provided, the system will automatically assign site_code and card_number from the pool.
Request
# Base64 encode the JSON
JSON=$(cat <<EOF
{
"card_template_id": "0xd3adb00b5",
"employee_id": "123456789",
"tag_id": "DDEADB33FB00B5",
"allow_on_multiple_devices": true,
"full_name": "Employee name",
"email": "[email protected]",
"phone_number": "+19547212241",
"classification": "full_time",
"start_date": "$(date -u +"%Y-%m-%dT%H:%M:%S.%3NZ")",
"expiration_date": "$(date -u -v+3m +"%Y-%m-%dT%H:%M:%S.%3NZ")",
"employee_photo": "[image_in_base64_encoded_format]",
"title": "Engineering Manager"
}
EOF)
JSON_B64=$(echo $JSON | base64)
# Add salt and hash
HASH=$(echo -n "$SHARED_SECRET$JSON_B64" | openssl sha256 | awk '{print $2}')
# Send curl request
curl -v \
-X POST \
-H 'X-ACCT-ID: 123' \
-H "X-PAYLOAD-SIG: $HASH" \
-d '{"example": true}' \
"https://api.accessgrid.com/v1/key-cards"
require('accessgrid')
acct_id = ENV['ACCOUNT_ID']
secret_key = ENV['SECRET_KET']
client = AccessGrid.new(acct_id, secret_key)
card = client.access_cards.provision(
card_template_id: "0xd3adb00b5",
employee_id: "123456789",
tag_id: "DDEADB33FB00B5",
allow_on_multiple_devices: true,
full_name: "Employee name",
email: "[email protected]",
phone_number: "+19547212241",
classification: "full_time",
start_date: "2026-01-14T11:04:10.556Z",
expiration_date: "2026-04-14T11:04:10.556Z",
employee_photo: "[image_in_base64_encoded_format]",
title: "Engineering Manager",
metadata: {
"department": "engineering",
"badge_type": "contractor"
}
)
puts "Install URL: #{card.url}"
import AccessGrid from 'accessgrid';
const accountId = process.env.ACCOUNT_ID;
const secretKey = process.env.SECRET_KEY;
const client = new AccessGrid(accountId, secretKey);
const provision = async () => {
try {
const card = await client.accessCards.provision({
cardTemplateId: "0xd3adb00b5",
employeeId: "123456789",
tagId: "DDEADB33FB00B5",
allowOnMultipleDevices: true,
fullName: "Employee name",
email: "[email protected]",
phoneNumber: "+19547212241",
classification: "full_time",
start_date: "2026-01-14T11:04:10.556Z",
expiration_date: "2026-04-14T11:04:10.556Z",
employeePhoto: "[image_in_base64_encoded_format]",
title: "Engineering Manager",
metadata: {
department: "engineering",
badgeType: "contractor"
}
});
console.log(`Install URL: ${card.url}`);
} catch (error) {
console.error('Error provisioning Access Pass:', error);
}
};
provision();
from accessgrid import AccessGrid
import os
from datetime import datetime, timezone
account_id = os.getenv('ACCOUNT_ID')
secret_key = os.getenv('SECRET_KEY')
client = AccessGrid(account_id, secret_key)
# Current time in ISO format with UTC timezone
current_time = datetime.now(timezone.utc).isoformat(timespec='milliseconds')
card = client.access_cards.provision(
card_template_id="0xd3adb00b5",
employee_id="123456789",
tag_id="DDEADB33FB00B5",
allow_on_multiple_devices=True,
full_name="Employee name",
email="[email protected]",
phone_number="+19547212241",
classification="full_time",
start_date="2026-01-14T11:04:10.556Z",
expiration_date="2026-04-14T11:04:10.556Z",
employee_photo="[image_in_base64_encoded_format]",
title="Engineering Manager",
metadata={
"department": "engineering",
"badge_type": "contractor"
}
)
print(f"Install URL: {card.url}")
package main
import (
"fmt"
"os"
"time"
"github.com/accessgrid/accessgrid-go" // hypothetical import path
)
func main() {
accountID := os.Getenv("ACCOUNT_ID")
secretKey := os.Getenv("SECRET_KEY")
client, err := accessgrid.NewClient(accountID, secretKey)
if err != nil {
fmt.Printf("Error creating client: %v\n", err)
return
}
params := accessgrid.ProvisionParams{
CardTemplateID: "0xd3adb00b5",
EmployeeID: "123456789",
TagID: "DDEADB33FB00B5",
AllowOnMultipleDevices: true,
FullName: "Employee name",
Email: "[email protected]",
PhoneNumber: "+19547212241",
Classification: "full_time",
StartDate: time.Now().UTC().Format(time.RFC3339Nano),
ExpirationDate: "2025-02-22T21:04:03.664Z",
EmployeePhoto: "[image_in_base64_encoded_format]",
Title: "Engineering Manager",
Metadata: map[string]interface{}{
"department": "engineering",
"badge_type": "contractor",
},
}
card, err := client.AccessCards.Provision(params)
if err != nil {
fmt.Printf("Error provisioning card: %v\n", err)
return
}
fmt.Printf("Install URL: %s\n", card.URL)
}
using AccessGrid;
using Microsoft.Extensions.Configuration;
// Assuming you're in a class
public async Task ProvisionCardAsync()
{
var accountId = Environment.GetEnvironmentVariable("ACCOUNT_ID");
var secretKey = Environment.GetEnvironmentVariable("SECRET_KEY");
var client = new AccessGridClient(accountId, secretKey);
var card = await client.AccessCards.ProvisionAsync(new ProvisionCardRequest
{
CardTemplateId = "0xd3adb00b5",
EmployeeId = "123456789",
TagId = "DDEADB33FB00B5",
AllowOnMultipleDevices = true,
FullName = "Employee name",
Email = "[email protected]",
PhoneNumber = "+19547212241",
Classification = "full_time",
StartDate = DateTime.UtcNow,
ExpirationDate = DateTime.Parse("2025-02-22T21:04:03.664Z").ToUniversalTime(),
EmployeePhoto = "[image_in_base64_encoded_format]",
Title = "Engineering Manager",
Metadata = new Dictionary<string, object>
{
["department"] = "engineering",
["badge_type"] = "contractor"
}
});
Console.WriteLine($"Install URL: {card.Url}");
}
// The request model would likely be defined like this
public class ProvisionCardRequest
{
public string CardTemplateId { get; set; } = string.Empty;
public string EmployeeId { get; set; } = string.Empty;
public string TagId { get; set; } = string.Empty;
public bool AllowOnMultipleDevices { get; set; }
public string FullName { get; set; } = string.Empty;
public string Email { get; set; } = string.Empty;
public string PhoneNumber { get; set; } = string.Empty;
public string Classification { get; set; } = string.Empty;
public DateTime StartDate { get; set; }
public DateTime ExpirationDate { get; set; }
public string EmployeePhoto { get; set; } = string.Empty;
public string Title { get; set; } = string.Empty;
}
// And the response might look like this
public class ProvisionCardResponse
{
public string Url { get; set; } = string.Empty;
// Other properties that might come back from the API...
}
import com.organization.accessgrid.AccessGridClient;
import com.organization.accessgrid.model.ProvisionCardRequest;
import com.organization.accessgrid.model.Card;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
public class AccessCardService {
private final AccessGridClient client;
public AccessCardService() {
String accountId = System.getenv("ACCOUNT_ID");
String secretKey = System.getenv("SECRET_KEY");
this.client = new AccessGridClient(accountId, secretKey);
}
public Card provisionCard() throws AccessGridException {
ProvisionCardRequest request = ProvisionCardRequest.builder()
.cardTemplateId("0xd3adb00b5")
.employeeId("123456789")
.tagId("DDEADB33FB00B5")
.allowOnMultipleDevices(true)
.fullName("Employee name")
.email("[email protected]")
.phoneNumber("+19547212241")
.classification("full_time")
.startDate(ZonedDateTime.now().format(DateTimeFormatter.ISO_INSTANT))
.expirationDate("2025-02-22T21:04:03.664Z")
.employeePhoto("[image_in_base64_encoded_format]")
.title("Engineering Manager")
.metadata(Map.of(
"department", "engineering",
"badge_type", "contractor"
))
.build();
Card card = client.accessCards().provision(request);
System.out.printf("Install URL: %s%n", card.getUrl());
return card;
}
}
// The request model would likely be defined like this
@Getter
@Builder
public class ProvisionCardRequest {
private final String cardTemplateId;
private final String employeeId;
private final String tagId;
private final boolean allowOnMultipleDevices;
private final String fullName;
private final String email;
private final String phoneNumber;
private final String classification;
private final String startDate;
private final String expirationDate;
private final String employeePhoto;
private final String title;
}
// And the response model
@Getter
public class Card {
private final String url;
// Other properties...
}
// Usage example
public class Example {
public static void main(String[] args) {
try {
AccessCardService service = new AccessCardService();
Card card = service.provisionCard();
} catch (AccessGridException e) {
System.err.println("Error provisioning card: " + e.getMessage());
}
}
}
<?php
require 'vendor/autoload.php';
use AccessGridClient;
$accountId = $_ENV['ACCOUNT_ID'];
$secretKey = $_ENV['SECRET_KEY'];
$client = new Client($accountId, $secretKey);
$card = $client->accessCards->provision([
'card_template_id' => '0xd3adb00b5',
'employee_id' => '123456789',
'tag_id' => 'DDEADB33FB00B5',
'allow_on_multiple_devices' => true,
'full_name' => 'Employee name',
'email' => '[email protected]',
'phone_number' => '+19547212241',
'classification' => 'full_time',
'start_date' => (new DateTime('now', new DateTimeZone('UTC')))->format('c'),
'expiration_date' => '2025-02-22T21:04:03.664Z',
'employee_photo' => '[image_in_base64_encoded_format]',
'title' => 'Engineering Manager',
'metadata' => [
'department' => 'engineering',
'badge_type' => 'contractor'
]
]);
echo "Install URL: {$card->url}\n";
Response
{
"status": "success",
"install_url": "https://install.accessgrid.io/pass/key_a91c7e23",
"id": "key_a91c7e23",
"state": "active",
"full_name": "Employee name",
"expiration_date": "2026-03-29T15:34:40.072Z",
"metadata": {
"department": "engineering",
"badgeType": "contractor"
},
"card_number": "8472-1093-5561",
"site_code": "ENG-HQ-01",
"file_data": {
"file_name": "access_pass.pkpass",
"file_size": 31245,
"content_type": "application/vnd.apple.pkpass"
},
"devices": [
{
"id": "dev_7f3b2a9c",
"platform": "ios",
"device_type": "iphone",
"status": "active"
},
{
"id": "dev_c91d88aa",
"platform": "android",
"device_type": "phone",
"status": "pending_install"
}
]
}
Get Issued Pass
Retrieve details about a specific issued Access Pass, including its state, devices, and metadata
card_id
string
Unique identifier of the Access Pass to retrieve, sent as part of the URL
Request
# Base64 encode the JSON
JSON=$(cat <<EOF
{
"card_id": "0xc4rd1d"
}
EOF)
JSON_B64=$(echo $JSON | base64)
# Add salt and hash
HASH=$(echo -n "$SHARED_SECRET$JSON_B64" | openssl sha256 | awk '{print $2}')
# Send curl request
curl -v \
-X GET \
-H 'X-ACCT-ID: 123' \
-H "X-PAYLOAD-SIG: $HASH" \
"https://api.accessgrid.com/v1/key-cards/0xc4rd1d"
require 'accessgrid'
acct_id = ENV['ACCOUNT_ID']
secret_key = ENV['SECRET_KEY']
client = AccessGrid.new(acct_id, secret_key)
card = client.access_cards.get(card_id: "0xc4rd1d")
puts "Card ID: #{card.id}"
puts "State: #{card.state}"
puts "Full Name: #{card.full_name}"
puts "Install URL: #{card.install_url}"
puts "Expiration Date: #{card.expiration_date}"
puts "Card Number: #{card.card_number}"
puts "Site Code: #{card.site_code}"
puts "Devices: #{card.devices.length}"
puts "Metadata: #{card.metadata}"
import AccessGrid from 'accessgrid';
const accountId = process.env.ACCOUNT_ID;
const secretKey = process.env.SECRET_KEY;
const client = new AccessGrid(accountId, secretKey);
const getCard = async () => {
try {
const card = await client.accessCards.get({
cardId: "0xc4rd1d"
});
console.log('Card ID:', card.id);
console.log('State:', card.state);
console.log('Full Name:', card.fullName);
console.log('Install URL:', card.installUrl);
console.log('Expiration Date:', card.expirationDate);
console.log('Card Number:', card.cardNumber);
console.log('Site Code:', card.siteCode);
console.log('Devices:', card.devices);
console.log('Metadata:', card.metadata);
} catch (error) {
console.error('Error retrieving Access Pass:', error);
}
};
getCard();
from accessgrid import AccessGrid
import os
account_id = os.getenv('ACCOUNT_ID')
secret_key = os.getenv('SECRET_KEY')
client = AccessGrid(account_id, secret_key)
card = client.access_cards.get(card_id="0xc4rd1d")
print(f"Card ID: {card.id}")
print(f"State: {card.state}")
print(f"Full Name: {card.full_name}")
print(f"Install URL: {card.install_url}")
print(f"Expiration Date: {card.expiration_date}")
print(f"Card Number: {card.card_number}")
print(f"Site Code: {card.site_code}")
print(f"Devices: {len(card.devices)}")
print(f"Metadata: {card.metadata}")
package main
import (
"fmt"
"os"
"github.com/accessgrid/accessgrid-go"
)
func main() {
accountID := os.Getenv("ACCOUNT_ID")
secretKey := os.Getenv("SECRET_KEY")
client, err := accessgrid.NewClient(accountID, secretKey)
if err != nil {
fmt.Printf("Error creating client: %v\n", err)
return
}
card, err := client.AccessCards.Get("0xc4rd1d")
if err != nil {
fmt.Printf("Error retrieving card: %v\n", err)
return
}
fmt.Printf("Card ID: %s\n", card.ID)
fmt.Printf("State: %s\n", card.State)
fmt.Printf("Full Name: %s\n", card.FullName)
fmt.Printf("Install URL: %s\n", card.InstallURL)
fmt.Printf("Expiration Date: %s\n", card.ExpirationDate)
fmt.Printf("Card Number: %s\n", card.CardNumber)
fmt.Printf("Site Code: %s\n", card.SiteCode)
fmt.Printf("Devices: %d\n", len(card.Devices))
fmt.Printf("Metadata: %v\n", card.Metadata)
}
using AccessGrid;
public async Task GetCardAsync()
{
var accountId = Environment.GetEnvironmentVariable("ACCOUNT_ID");
var secretKey = Environment.GetEnvironmentVariable("SECRET_KEY");
var client = new AccessGridClient(accountId, secretKey);
var card = await client.AccessCards.GetAsync("0xc4rd1d");
Console.WriteLine($"Card ID: {card.Id}");
Console.WriteLine($"State: {card.State}");
Console.WriteLine($"Full Name: {card.FullName}");
Console.WriteLine($"Install URL: {card.InstallUrl}");
Console.WriteLine($"Expiration Date: {card.ExpirationDate}");
Console.WriteLine($"Card Number: {card.CardNumber}");
Console.WriteLine($"Site Code: {card.SiteCode}");
Console.WriteLine($"Devices: {card.Devices.Count}");
Console.WriteLine($"Metadata: {card.Metadata}");
}
import com.organization.accessgrid.AccessGridClient;
import com.organization.accessgrid.model.Card;
public class AccessCardService {
private final AccessGridClient client;
public AccessCardService() {
String accountId = System.getenv("ACCOUNT_ID");
String secretKey = System.getenv("SECRET_KEY");
this.client = new AccessGridClient(accountId, secretKey);
}
public void getCard() throws AccessGridException {
Card card = client.accessCards().get("0xc4rd1d");
System.out.println("Card ID: " + card.getId());
System.out.println("State: " + card.getState());
System.out.println("Full Name: " + card.getFullName());
System.out.println("Install URL: " + card.getInstallUrl());
System.out.println("Expiration Date: " + card.getExpirationDate());
System.out.println("Card Number: " + card.getCardNumber());
System.out.println("Site Code: " + card.getSiteCode());
System.out.println("Devices: " + card.getDevices().size());
System.out.println("Metadata: " + card.getMetadata());
}
}
<?php
require 'vendor/autoload.php';
use AccessGridClient;
$accountId = $_ENV['ACCOUNT_ID'];
$secretKey = $_ENV['SECRET_KEY'];
$client = new Client($accountId, $secretKey);
$card = $client->accessCards->get('0xc4rd1d');
echo "Card ID: {$card->id}\n";
echo "State: {$card->state}\n";
echo "Full Name: {$card->full_name}\n";
echo "Install URL: {$card->install_url}\n";
echo "Expiration Date: {$card->expiration_date}\n";
echo "Card Number: {$card->card_number}\n";
echo "Site Code: {$card->site_code}\n";
echo "Devices: " . count($card->devices) . "\n";
echo "Metadata: " . json_encode($card->metadata) . "\n";
Response
Empty
Update Access Pass
When you need to make an informational update to an Access Pass such as name, photo, etc
card_id
string
Unique identifier of the Access Pass to update, sent as part of the URL
employee_id
nullable string
Updated unique identifier for the employee
full_name
nullable string
Updated full name of the Access Pass owner
classification
nullable string
Updated employment classification (e.g., full_time, contractor)
expiration_date
nullable string
Updated ISO8601 timestamp when the card expires
employee_photo
nullable string
Updated base64 encoded PNG image of the employee (max 10MB)
title
nullable string
Updated job title or department of the employee
file_data
nullable string
Up to 64 characters of hexadecimal data (0-9, A-F). Only used when implementing proprietary data formats.
is_pass_ready_to_transact
nullable boolean
Only for 'hotel' use case. Whether the pass is ready to be used for NFC transactions
tile_data
nullable object
Only for 'hotel' use case. Data for the hotel tile display
checkInAvailableWindowStartDateTime
nullable string
ISO8601 timestamp with timezone. Required if isCheckedIn is missing or false
checkInAvailableWindowEndDateTime
nullable string
ISO8601 timestamp with timezone. Required if isCheckedIn is missing or false
checkInDateTime
nullable string
ISO8601 timestamp with timezone. Required if isCheckedIn is true
checkInURL
nullable string
URL for remote check-in. Only used if isCheckedIn is missing or false
isCheckedIn
nullable boolean
Whether the guest has checked in
numberOfRoomsReserved
nullable integer
Number of rooms reserved. Must match the number of roomNumbers if both are present
roomNumbers
nullable array
Array of room numbers. Must match the number of numberOfRoomsReserved if both are present
reservations
nullable object
Only for 'hotel' use case. Data for the hotel reservation
checkInDateTime
nullable string
ISO8601 timestamp with timezone. Required if isCheckedIn is true
isCheckedIn
nullable boolean
Whether the guest has checked in
numberOfRoomsReserved
nullable integer
Number of rooms reserved. Must match the number of roomNumbers if both are present
propertyLocation
nullable string
Location of the property (e.g., 'Key West')
propertyName
nullable string
Name of the property (e.g., 'Hyatt Centric Resort & Spa')
propertyMapUrl
nullable string
URL to a map of the property
propertyCategory
nullable string
Category of the property. If provided, must be 'travel'
restaurantVoucher
nullable string
Optional voucher for restaurant services
reservationEndDateTime
nullable string
ISO8601 timestamp with timezone for reservation end
reservationNumber
nullable string
Confirmation number for the reservation
reservationStartDateTime
nullable string
ISO8601 timestamp with timezone for reservation start
roomNumbers
nullable array
Array of room numbers. Must match the number of numberOfRoomsReserved if both are present
metadata
nullable object
Custom JSON object for storing additional metadata associated with the access pass. Can contain any valid JSON data.
Request
# Base64 encode the JSON
JSON=$(cat <<EOF
{
"employee_id": "987654321",
"full_name": "Updated Employee Name",
"classification": "contractor",
"expiration_date": "2025-02-22T21:04:03.664Z",
"title": "Senior Developer"
}
EOF)
JSON_B64=$(echo $JSON | base64)
# Add salt and hash
HASH=$(echo -n "$SHARED_SECRET$JSON_B64" | openssl sha256 | awk '{print $2}')
curl -v \
-X PATCH \
-H 'X-ACCT-ID: 123' \
-H "X-PAYLOAD-SIG: $HASH" \
-d '{
"card_id": "0xc4rd1d",
"employee_id": "987654321",
"full_name": "Updated Employee Name",
"classification": "contractor",
"expiration_date": "2025-02-22T21:04:03.664Z",
"title": "Senior Developer"
}' \
"https://api.accessgrid.com/v1/key-cards/{card_id}"
require 'accessgrid'
acct_id = ENV['ACCOUNT_ID']
secret_key = ENV['SECRET_KEY']
client = AccessGrid.new(acct_id, secret_key)
card = client.access_cards.update(
card_id: "0xc4rd1d",
employee_id: "987654321",
full_name: "Updated Employee Name",
classification: "contractor",
expiration_date: "2026-04-14T11:04:10.556Z",
employee_photo: "[image_in_base64_encoded_format]",
title: "Senior Developer"
)
puts "Card updated successfully"
import AccessGrid from 'accessgrid';
const accountId = process.env.ACCOUNT_ID;
const secretKey = process.env.SECRET_KEY;
const client = new AccessGrid(accountId, secretKey);
const update = async () => {
try {
const card = await client.accessCards.update({
cardId: "0xc4rd1d",
employeeId: "987654321",
fullName: "Updated Employee Name",
classification: "contractor",
expirationDate: "2025-02-22T21:04:03.664Z",
employeePhoto: "[image_in_base64_encoded_format]",
title: "Senior Developer"
});
console.log('Card updated successfully');
} catch (error) {
console.error('Error updating Access Pass:', error);
}
};
update();
from accessgrid import AccessGrid
import os
from datetime import datetime, timezone, timedelta
account_id = os.getenv('ACCOUNT_ID')
secret_key = os.getenv('SECRET_KEY')
client = AccessGrid(account_id, secret_key)
card = client.access_cards.update(
card_id="0xc4rd1d",
employee_id="987654321",
full_name="Updated Employee Name",
classification="contractor",
expiration_date=(datetime.now(timezone.utc) + timedelta(days=90)).isoformat(),
employee_photo="[image_in_base64_encoded_format]",
title="Senior Developer"
)
print("Card updated successfully")
package main
import (
"fmt"
"os"
"time"
"github.com/accessgrid/accessgrid-go"
)
func main() {
accountID := os.Getenv("ACCOUNT_ID")
secretKey := os.Getenv("SECRET_KEY")
client, err := accessgrid.NewClient(accountID, secretKey)
if err != nil {
fmt.Printf("Error creating client: %v\n", err)
return
}
params := accessgrid.UpdateParams{
CardID: "0xc4rd1d",
EmployeeID: "987654321",
FullName: "Updated Employee Name",
Classification: "contractor",
ExpirationDate: time.Now().UTC().AddDate(0, 3, 0).Format(time.RFC3339),
EmployeePhoto: "[image_in_base64_encoded_format]",
Title: "Senior Developer",
}
card, err := client.AccessCards.Update(params)
if err != nil {
fmt.Printf("Error updating card: %v\n", err)
return
}
fmt.Println("Card updated successfully")
}
using AccessGrid;
public async Task UpdateCardAsync()
{
var accountId = Environment.GetEnvironmentVariable("ACCOUNT_ID");
var secretKey = Environment.GetEnvironmentVariable("SECRET_KEY");
var client = new AccessGridClient(accountId, secretKey);
await client.AccessCards.UpdateAsync(new UpdateCardRequest
{
CardId = "0xc4rd1d",
EmployeeId = "987654321",
FullName = "Updated Employee Name",
Classification = "contractor",
ExpirationDate = DateTime.UtcNow.AddMonths(3),
EmployeePhoto = "[image_in_base64_encoded_format]",
Title = "Senior Developer"
});
Console.WriteLine("Card updated successfully");
}
import com.organization.accessgrid.AccessGridClient;
import com.organization.accessgrid.model.UpdateCardRequest;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
public class AccessCardService {
private final AccessGridClient client;
public AccessCardService() {
String accountId = System.getenv("ACCOUNT_ID");
String secretKey = System.getenv("SECRET_KEY");
this.client = new AccessGridClient(accountId, secretKey);
}
public void updateCard() throws AccessGridException {
UpdateCardRequest request = UpdateCardRequest.builder()
.cardId("0xc4rd1d")
.employeeId("987654321")
.fullName("Updated Employee Name")
.classification("contractor")
.expirationDate(ZonedDateTime.now().plusMonths(3).format(DateTimeFormatter.ISO_INSTANT))
.employeePhoto("[image_in_base64_encoded_format]")
.title("Senior Developer")
.build();
client.accessCards().update(request);
System.out.println("Card updated successfully");
}
}
<?php
require 'vendor/autoload.php';
use AccessGridClient;
$accountId = $_ENV['ACCOUNT_ID'];
$secretKey = $_ENV['SECRET_KEY'];
$client = new Client($accountId, $secretKey);
$card = $client->accessCards->update([
'card_id' => '0xc4rd1d',
'employee_id' => '987654321',
'full_name' => 'Updated Employee Name',
'classification' => 'contractor',
'expiration_date' => (new DateTime('now', new DateTimeZone('UTC')))->modify('+3 months')->format('c'),
'employee_photo' => '[image_in_base64_encoded_format]',
'title' => 'Senior Developer'
]);
echo "Card updated successfully\n";
Response
Empty
Suspend Access Pass
When you need to temporarily disable an Access Pass for a short period of time
card_id
string
Unique identifier of the Access Pass to suspend, sent as part of the URL
Request
# Base64 encode the JSON
JSON='{ "card_id": "0xc4rd1d" }'
JSON_B64=$(echo $JSON | base64)
# Add salt and hash
HASH=$(echo -n "$SHARED_SECRET$JSON_B64" | openssl sha256 | awk '{print $2}')
curl -v \
-X POST \
-H 'X-ACCT-ID: 123' \
-H "X-PAYLOAD-SIG: $HASH" \
"https://api.accessgrid.com/v1/key-cards/{card_id}/suspend"
require 'accessgrid'
acct_id = ENV['ACCOUNT_ID']
secret_key = ENV['SECRET_KEY']
client = AccessGrid.new(acct_id, secret_key)
card = client.access_cards.suspend(
card_id: "0xc4rd1d"
)
puts "Card suspended successfully"
import AccessGrid from 'accessgrid';
const accountId = process.env.ACCOUNT_ID;
const secretKey = process.env.SECRET_KEY;
const client = new AccessGrid(accountId, secretKey);
const suspend = async () => {
try {
await client.accessCards.suspend({
cardId: "0xc4rd1d"
});
console.log('Card suspended successfully');
} catch (error) {
console.error('Error suspending Access Pass:', error);
}
};
suspend();
from accessgrid import AccessGrid
import os
account_id = os.getenv('ACCOUNT_ID')
secret_key = os.getenv('SECRET_KEY')
client = AccessGrid(account_id, secret_key)
card = client.access_cards.suspend(
card_id="0xc4rd1d"
)
print("Card suspended successfully")
package main
import (
"fmt"
"os"
"github.com/accessgrid/accessgrid-go"
)
func main() {
accountID := os.Getenv("ACCOUNT_ID")
secretKey := os.Getenv("SECRET_KEY")
client, err := accessgrid.NewClient(accountID, secretKey)
if err != nil {
fmt.Printf("Error creating client: %v\n", err)
return
}
err = client.AccessCards.Suspend("0xc4rd1d")
if err != nil {
fmt.Printf("Error suspending card: %v\n", err)
return
}
fmt.Println("Card suspended successfully")
}
using AccessGrid;
public async Task SuspendCardAsync()
{
var accountId = Environment.GetEnvironmentVariable("ACCOUNT_ID");
var secretKey = Environment.GetEnvironmentVariable("SECRET_KEY");
var client = new AccessGridClient(accountId, secretKey);
await client.AccessCards.SuspendAsync("0xc4rd1d");
Console.WriteLine("Card suspended successfully");
}
import com.organization.accessgrid.AccessGridClient;
public class AccessCardService {
private final AccessGridClient client;
public AccessCardService() {
String accountId = System.getenv("ACCOUNT_ID");
String secretKey = System.getenv("SECRET_KEY");
this.client = new AccessGridClient(accountId, secretKey);
}
public void suspendCard() throws AccessGridException {
client.accessCards().suspend("0xc4rd1d");
System.out.println("Card suspended successfully");
}
}
<?php
require 'vendor/autoload.php';
use AccessGridClient;
$accountId = $_ENV['ACCOUNT_ID'];
$secretKey = $_ENV['SECRET_KEY'];
$client = new Client($accountId, $secretKey);
$client->accessCards->suspend([
'card_id' => '0xc4rd1d'
]);
echo "Card suspended successfully\n";
Response
Empty
Resume Access Pass
If you have previously suspended an Access Pass, you can re-enable it with the resume action
card_id
string
Unique identifier of the Access Pass to resume, sent as part of the URL
Request
# Base64 encode the JSON
JSON='{ "card_id": "0xc4rd1d" }'
JSON_B64=$(echo $JSON | base64)
# Add salt and hash
HASH=$(echo -n "$SHARED_SECRET$JSON_B64" | openssl sha256 | awk '{print $2}')
curl -v \
-X POST \
-H 'X-ACCT-ID: 123' \
-H "X-PAYLOAD-SIG: $HASH" \
-d '{
"card_id": "0xc4rd1d"
}' \
"https://api.accessgrid.com/v1/key-cards/{card_id}/resume"
require 'accessgrid'
acct_id = ENV['ACCOUNT_ID']
secret_key = ENV['SECRET_KEY']
client = AccessGrid.new(acct_id, secret_key)
card = client.access_cards.resume(
card_id: "0xc4rd1d"
)
puts "Card resumed successfully"
import AccessGrid from 'accessgrid';
const accountId = process.env.ACCOUNT_ID;
const secretKey = process.env.SECRET_KEY;
const client = new AccessGrid(accountId, secretKey);
const resume = async () => {
try {
await client.accessCards.resume({
cardId: "0xc4rd1d"
});
console.log('Card resumed successfully');
} catch (error) {
console.error('Error resuming Access Pass:', error);
}
};
resume();
from accessgrid import AccessGrid
import os
account_id = os.getenv('ACCOUNT_ID')
secret_key = os.getenv('SECRET_KEY')
client = AccessGrid(account_id, secret_key)
card = client.access_cards.resume(
card_id="0xc4rd1d"
)
print("Card resumed successfully")
package main
import (
"fmt"
"os"
"github.com/accessgrid/accessgrid-go"
)
func main() {
accountID := os.Getenv("ACCOUNT_ID")
secretKey := os.Getenv("SECRET_KEY")
client, err := accessgrid.NewClient(accountID, secretKey)
if err != nil {
fmt.Printf("Error creating client: %v\n", err)
return
}
err = client.AccessCards.Resume("0xc4rd1d")
if err != nil {
fmt.Printf("Error resuming card: %v\n", err)
return
}
fmt.Println("Card resumed successfully")
}
using AccessGrid;
public async Task ResumeCardAsync()
{
var accountId = Environment.GetEnvironmentVariable("ACCOUNT_ID");
var secretKey = Environment.GetEnvironmentVariable("SECRET_KEY");
var client = new AccessGridClient(accountId, secretKey);
await client.AccessCards.ResumeAsync("0xc4rd1d");
Console.WriteLine("Card resumed successfully");
}
import com.organization.accessgrid.AccessGridClient;
public class AccessCardService {
private final AccessGridClient client;
public AccessCardService() {
String accountId = System.getenv("ACCOUNT_ID");
String secretKey = System.getenv("SECRET_KEY");
this.client = new AccessGridClient(accountId, secretKey);
}
public void resumeCard() throws AccessGridException {
client.accessCards().resume("0xc4rd1d");
System.out.println("Card resumed successfully");
}
}
<?php
require 'vendor/autoload.php';
use AccessGridClient;
$accountId = $_ENV['ACCOUNT_ID'];
$secretKey = $_ENV['SECRET_KEY'];
$client = new Client($accountId, $secretKey);
$client->accessCards->resume([
'card_id' => '0xc4rd1d'
]);
echo "Card resumed successfully\n";
Response
Empty
Unlink Access Pass
If you'd like to force the removal of an Access Pass from it's current holder - unlinking does not make a key uninstallable, it simply disables it on the users phone.
card_id
string
Unique identifier of the Access Pass to unlink from its current holder, sent as part of the URL
Request
# Base64 encode the JSON
JSON='{ "card_id": "0xc4rd1d" }'
JSON_B64=$(echo $JSON | base64)
# Add salt and hash
HASH=$(echo -n "$SHARED_SECRET$JSON_B64" | openssl sha256 | awk '{print $2}')
curl -v \
-X POST \
-H 'X-ACCT-ID: 123' \
-H "X-PAYLOAD-SIG: $HASH" \
-d '{
"card_id": "0xc4rd1d"
}' \
"https://api.accessgrid.com/v1/key-cards/{card_id}/unlink"
require 'accessgrid'
acct_id = ENV['ACCOUNT_ID']
secret_key = ENV['SECRET_KEY']
client = AccessGrid.new(acct_id, secret_key)
card = client.access_cards.unlink(
card_id: "0xc4rd1d"
)
puts "Card unlinked successfully"
import AccessGrid from 'accessgrid';
const accountId = process.env.ACCOUNT_ID;
const secretKey = process.env.SECRET_KEY;
const client = new AccessGrid(accountId, secretKey);
const unlink = async () => {
try {
await client.accessCards.unlink({
cardId: "0xc4rd1d"
});
console.log('Card unlinked successfully');
} catch (error) {
console.error('Error unlinking Access Pass:', error);
}
};
unlink();
from accessgrid import AccessGrid
import os
account_id = os.getenv('ACCOUNT_ID')
secret_key = os.getenv('SECRET_KEY')
client = AccessGrid(account_id, secret_key)
card = client.access_cards.unlink(
card_id="0xc4rd1d"
)
print("Card unlinked successfully")
package main
import (
"fmt"
"os"
"github.com/accessgrid/accessgrid-go"
)
func main() {
accountID := os.Getenv("ACCOUNT_ID")
secretKey := os.Getenv("SECRET_KEY")
client, err := accessgrid.NewClient(accountID, secretKey)
if err != nil {
fmt.Printf("Error creating client: %v\n", err)
return
}
err = client.AccessCards.Unlink("0xc4rd1d")
if err != nil {
fmt.Printf("Error unlinking card: %v\n", err)
return
}
fmt.Println("Card unlinked successfully")
}
using AccessGrid;
public async Task UnlinkCardAsync()
{
var accountId = Environment.GetEnvironmentVariable("ACCOUNT_ID");
var secretKey = Environment.GetEnvironmentVariable("SECRET_KEY");
var client = new AccessGridClient(accountId, secretKey);
await client.AccessCards.UnlinkAsync("0xc4rd1d");
Console.WriteLine("Card unlinked successfully");
}
import com.organization.accessgrid.AccessGridClient;
public class AccessCardService {
private final AccessGridClient client;
public AccessCardService() {
String accountId = System.getenv("ACCOUNT_ID");
String secretKey = System.getenv("SECRET_KEY");
this.client = new AccessGridClient(accountId, secretKey);
}
public void unlinkCard() throws AccessGridException {
client.accessCards().unlink("0xc4rd1d");
System.out.println("Card unlinked successfully");
}
}
<?php
require 'vendor/autoload.php';
use AccessGridClient;
$accountId = $_ENV['ACCOUNT_ID'];
$secretKey = $_ENV['SECRET_KEY'];
$client = new Client($accountId, $secretKey);
$client->accessCards->unlink([
'card_id' => '0xc4rd1d'
]);
echo "Card unlinked successfully\n";
Response
Empty
Delete Access Pass
If you'd like to delete Access Pass and prevent additional installs - deleting a key unlinks it and makes prevents any additional installs
card_id
string
Unique identifier of the Access Pass to delete, sent as part of the URL
Request
# Base64 encode the JSON
JSON='{ "card_id": "0xc4rd1d" }'
JSON_B64=$(echo $JSON | base64)
# Add salt and hash
HASH=$(echo -n "$SHARED_SECRET$JSON_B64" | openssl sha256 | awk '{print $2}')
curl -v \
-X POST \
-H 'X-ACCT-ID: 123' \
-H "X-PAYLOAD-SIG: $HASH" \
-d '{
"card_id": "0xc4rd1d"
}' \
"https://api.accessgrid.com/v1/key-cards/{card_id}/delete"
require 'accessgrid'
acct_id = ENV['ACCOUNT_ID']
secret_key = ENV['SECRET_KEY']
client = AccessGrid.new(acct_id, secret_key)
card = client.access_cards.delete(
card_id: "0xc4rd1d"
)
puts "Card deleted successfully"
import AccessGrid from 'accessgrid';
const accountId = process.env.ACCOUNT_ID;
const secretKey = process.env.SECRET_KEY;
const client = new AccessGrid(accountId, secretKey);
const del = async () => {
try {
await client.accessCards.delete({
cardId: "0xc4rd1d"
});
console.log('Card delete successfully');
} catch (error) {
console.error('Error deleting Access Pass:', error);
}
};
del();
from accessgrid import AccessGrid
import os
account_id = os.getenv('ACCOUNT_ID')
secret_key = os.getenv('SECRET_KEY')
client = AccessGrid(account_id, secret_key)
card = client.access_cards.delete(
card_id="0xc4rd1d"
)
print("Card deleted successfully")
package main
import (
"fmt"
"os"
"github.com/accessgrid/accessgrid-go"
)
func main() {
accountID := os.Getenv("ACCOUNT_ID")
secretKey := os.Getenv("SECRET_KEY")
client, err := accessgrid.NewClient(accountID, secretKey)
if err != nil {
fmt.Printf("Error creating client: %v\n", err)
return
}
err = client.AccessCards.Delete("0xc4rd1d")
if err != nil {
fmt.Printf("Error deleting card: %v\n", err)
return
}
fmt.Println("Card deleted successfully")
}
using AccessGrid;
public async Task DeleteCardAsync()
{
var accountId = Environment.GetEnvironmentVariable("ACCOUNT_ID");
var secretKey = Environment.GetEnvironmentVariable("SECRET_KEY");
var client = new AccessGridClient(accountId, secretKey);
await client.AccessCards.DeleteAsync("0xc4rd1d");
Console.WriteLine("Card deleted successfully");
}
import com.organization.accessgrid.AccessGridClient;
public class AccessCardService {
private final AccessGridClient client;
public AccessCardService() {
String accountId = System.getenv("ACCOUNT_ID");
String secretKey = System.getenv("SECRET_KEY");
this.client = new AccessGridClient(accountId, secretKey);
}
public void deleteCard() throws AccessGridException {
client.accessCards().delete("0xc4rd1d");
System.out.println("Card deleted successfully");
}
}
<?php
require 'vendor/autoload.php';
use AccessGridClient;
$accountId = $_ENV['ACCOUNT_ID'];
$secretKey = $_ENV['SECRET_KEY'];
$client = new Client($accountId, $secretKey);
$client->accessCards->delete([
'card_id' => '0xc4rd1d'
]);
echo "Card deleted successfully\n";
Response
Empty
Create Card Template
Only available for enterprise customers - allows you to create an empty card template using our console API.
name
string
The name to display for this card template in the AccessGrid console UI
platform
string
Must be one of `apple` or `google`
use_case
string
Must be `employee_badge` or `hotel`
protocol
string
Must be `desfire` or `seos` - HID Seos only available for enterprise customers
allow_on_multiple_devices
nullable boolean
False by default. Set to true if you'd like to enable the Access Passes issued using this template to exist on multiple devices (think phone and watch)
watch_count
nullable integer
Only allowed to be set if `allow_on_multiple_devices` is set to true. Any number between 1-5 is acceptable.
iphone_count
nullable integer
Only allowed to be set if `allow_on_multiple_devices` is set to true. Any number between 1-5 is acceptable.
design
nullable object
Object representing card template design
background_color
nullable string
Must be a 6 character hexadecimal value for the background color of the template, in the event that there is no background_image provided, i.e. #FFFFFF
label_color
nullable string
Must be a 6 character hexadecimal value for the label color for the template, i.e. #000000
label_secondary_color
nullable string
Must be a 6 character hexadecimal value for the secondary label color for the template, i.e. #333333
background_image
nullable string
Base64 encoded image of the card templates background
logo_image
nullable string
Base64 encoded image of the card templates logo (located in the top left)
icon_image
nullable string
Base64 encoded image of the card templates icon (used in sharing and notifications)
support_info
nullable object
Information for users that shows up on the back of the Access Pass
support_url
nullable string
Shows on the back of the issued Access Pass.
support_phone_number
nullable string
Shows on the back of the issued Access Pass.
support_email
nullable string
Shows on the back of the issued Access Pass.
privacy_policy_url
nullable string
Shows on the back of the issued Access Pass.
terms_and_conditions_url
nullable string
Shows on the back of the issued Access Pass.
metadata
nullable object
Custom JSON object for storing additional metadata associated with the pass template. Can contain any valid JSON data.
Request
curl -v \
-X POST \
-H 'X-ACCT-ID: 123' \
-H "X-PAYLOAD-SIG: $HASH" \
-d '{
"name": "Employee Access Pass",
"platform": "apple",
"use_case": "employee_badge",
"protocol": "desfire",
"allow_on_multiple_devices": true,
"watch_count": 2,
"iphone_count": 3,
"design": {
"background_color": "#FFFFFF",
"label_color": "#000000",
"label_secondary_color": "#333333",
"background_image": "[image_in_base64_encoded_format]",
"logo_image": "[image_in_base64_encoded_format]",
"icon_image": "[image_in_base64_encoded_format]"
},
"support_info": {
"support_url": "https://help.yourcompany.com",
"support_phone_number": "+1-555-123-4567",
"support_email": "[email protected]",
"privacy_policy_url": "https://yourcompany.com/privacy",
"terms_and_conditions_url": "https://yourcompany.com/terms"
},
"metadata": {
"version": "2.1",
"approval_status": "approved"
}
}' \
"https://api.accessgrid.com/v1/console/card-templates/"
require 'accessgrid'
acct_id = ENV['ACCOUNT_ID']
secret_key = ENV['SECRET_KEY']
client = AccessGrid.new(acct_id, secret_key)
template = client.console.create_template(
name: "Employee Access Pass",
platform: "apple",
use_case: "employee_badge",
protocol: "desfire",
allow_on_multiple_devices: true,
watch_count: 2,
iphone_count: 3,
design: {
background_color: "#FFFFFF",
label_color: "#000000",
label_secondary_color: "#333333",
background_image: "[image_in_base64_encoded_format]",
logo_image: "[image_in_base64_encoded_format]",
icon_image: "[image_in_base64_encoded_format]"
},
support_info: {
support_url: "https://help.yourcompany.com",
support_phone_number: "+1-555-123-4567",
support_email: "[email protected]",
privacy_policy_url: "https://yourcompany.com/privacy",
terms_and_conditions_url: "https://yourcompany.com/terms"
},
metadata: {
version: "2.1",
approval_status: "approved"
}
)
puts "Template created successfully: #{template.id}"
import AccessGrid from 'accessgrid';
const accountId = process.env.ACCOUNT_ID;
const secretKey = process.env.SECRET_KEY;
const client = new AccessGrid(accountId, secretKey);
const createTemplate = async () => {
try {
const template = await client.console.createTemplate({
name: "Employee Access Pass",
platform: "apple",
useCase: "employee_badge",
protocol: "desfire",
allowOnMultipleDevices: true,
watchCount: 2,
iphoneCount: 3,
design: {
backgroundColor: "#FFFFFF",
labelColor: "#000000",
labelSecondaryColor: "#333333",
backgroundImage: "[image_in_base64_encoded_format]",
logoImage: "[image_in_base64_encoded_format]",
iconImage: "[image_in_base64_encoded_format]"
},
supportInfo: {
supportUrl: "https://help.yourcompany.com",
supportPhoneNumber: "+1-555-123-4567",
supportEmail: "[email protected]",
privacyPolicyUrl: "https://yourcompany.com/privacy",
termsAndConditionsUrl: "https://yourcompany.com/terms"
},
metadata: {
version: "2.1",
approvalStatus: "approved"
}
});
console.log(`Template created successfully: ${template.id}`);
} catch (error) {
console.error('Error creating template:', error);
}
};
createTemplate();
from accessgrid import AccessGrid
import os
account_id = os.getenv('ACCOUNT_ID')
secret_key = os.getenv('SECRET_KEY')
client = AccessGrid(account_id, secret_key)
template = client.console.create_template(
name="Employee Access Pass",
platform="apple",
use_case="employee_badge",
protocol="desfire",
allow_on_multiple_devices=True,
watch_count=2,
iphone_count=3,
design={
"background_color": "#FFFFFF",
"label_color": "#000000",
"label_secondary_color": "#333333",
"background_image": "[image_in_base64_encoded_format]",
"logo_image": "[image_in_base64_encoded_format]",
"icon_image": "[image_in_base64_encoded_format]"
},
support_info={
"support_url": "https://help.yourcompany.com",
"support_phone_number": "+1-555-123-4567",
"support_email": "[email protected]",
"privacy_policy_url": "https://yourcompany.com/privacy",
"terms_and_conditions_url": "https://yourcompany.com/terms"
},
metadata={
"version": "2.1",
"approval_status": "approved"
}
)
print(f"Template created successfully: {template.id}")
package main
import (
"fmt"
"os"
"github.com/accessgrid/accessgrid-go"
)
func main() {
accountID := os.Getenv("ACCOUNT_ID")
secretKey := os.Getenv("SECRET_KEY")
client, err := accessgrid.NewClient(accountID, secretKey)
if err != nil {
fmt.Printf("Error creating client: %v\n", err)
return
}
design := accessgrid.TemplateDesign{
BackgroundColor: "#FFFFFF",
LabelColor: "#000000",
LabelSecondaryColor: "#333333",
BackgroundImage: "[image_in_base64_encoded_format]",
LogoImage: "[image_in_base64_encoded_format]",
IconImage: "[image_in_base64_encoded_format]",
}
supportInfo := accessgrid.SupportInfo{
SupportURL: "https://help.yourcompany.com",
SupportPhoneNumber: "+1-555-123-4567",
SupportEmail: "[email protected]",
PrivacyPolicyURL: "https://yourcompany.com/privacy",
TermsAndConditionsURL: "https://yourcompany.com/terms",
}
params := accessgrid.CreateTemplateParams{
Name: "Employee Access Pass",
Platform: "apple",
UseCase: "employee_badge",
Protocol: "desfire",
AllowOnMultipleDevices: true,
WatchCount: 2,
IPhoneCount: 3,
Design: design,
SupportInfo: supportInfo,
Metadata: map[string]interface{}{
"version": "2.1",
"approval_status": "approved",
},
}
template, err := client.Console.CreateTemplate(params)
if err != nil {
fmt.Printf("Error creating template: %v\n", err)
return
}
fmt.Printf("Template created successfully: %s\n", template.ID)
}
using AccessGrid;
public async Task CreateTemplateAsync()
{
var accountId = Environment.GetEnvironmentVariable("ACCOUNT_ID");
var secretKey = Environment.GetEnvironmentVariable("SECRET_KEY");
var client = new AccessGridClient(accountId, secretKey);
var template = await client.Console.CreateTemplateAsync(new CreateTemplateRequest
{
Name = "Employee Access Pass",
Platform = "apple",
UseCase = "employee_badge",
Protocol = "desfire",
AllowOnMultipleDevices = true,
WatchCount = 2,
IPhoneCount = 3,
Design = new TemplateDesign
{
BackgroundColor = "#FFFFFF",
LabelColor = "#000000",
LabelSecondaryColor = "#333333",
BackgroundImage = "[image_in_base64_encoded_format]",
LogoImage = "[image_in_base64_encoded_format]",
IconImage = "[image_in_base64_encoded_format]"
},
SupportInfo = new SupportInfo
{
SupportUrl = "https://help.yourcompany.com",
SupportPhoneNumber = "+1-555-123-4567",
SupportEmail = "[email protected]",
PrivacyPolicyUrl = "https://yourcompany.com/privacy",
TermsAndConditionsUrl = "https://yourcompany.com/terms"
},
Metadata = new Dictionary<string, object>
{
["version"] = "2.1",
["approval_status"] = "approved"
}
});
Console.WriteLine($"Template created successfully: {template.Id}");
}
import com.organization.accessgrid.AccessGridClient;
import com.organization.accessgrid.model.CreateTemplateRequest;
import com.organization.accessgrid.model.Template;
import com.organization.accessgrid.model.TemplateDesign;
import com.organization.accessgrid.model.SupportInfo;
public class ConsoleService {
private final AccessGridClient client;
public ConsoleService() {
String accountId = System.getenv("ACCOUNT_ID");
String secretKey = System.getenv("SECRET_KEY");
this.client = new AccessGridClient(accountId, secretKey);
}
public Template createTemplate() throws AccessGridException {
TemplateDesign design = TemplateDesign.builder()
.backgroundColor("#FFFFFF")
.labelColor("#000000")
.labelSecondaryColor("#333333")
.backgroundImage("[image_in_base64_encoded_format]")
.logoImage("[image_in_base64_encoded_format]")
.iconImage("[image_in_base64_encoded_format]")
.build();
SupportInfo supportInfo = SupportInfo.builder()
.supportUrl("https://help.yourcompany.com")
.supportPhoneNumber("+1-555-123-4567")
.supportEmail("[email protected]")
.privacyPolicyUrl("https://yourcompany.com/privacy")
.termsAndConditionsUrl("https://yourcompany.com/terms")
.build();
CreateTemplateRequest request = CreateTemplateRequest.builder()
.name("Employee Access Pass")
.platform("apple")
.useCase("employee_badge")
.protocol("desfire")
.allowOnMultipleDevices(true)
.watchCount(2)
.iphoneCount(3)
.design(design)
.supportInfo(supportInfo)
.metadata(Map.of(
"version", "2.1",
"approval_status", "approved"
))
.build();
Template template = client.console().createTemplate(request);
System.out.printf("Template created successfully: %s%n", template.getId());
return template;
}
}
<?php
require 'vendor/autoload.php';
use AccessGridClient;
$accountId = $_ENV['ACCOUNT_ID'];
$secretKey = $_ENV['SECRET_KEY'];
$client = new Client($accountId, $secretKey);
$template = $client->console->createTemplate([
'name' => 'Employee Access Pass',
'platform' => 'apple',
'use_case' => 'employee_badge',
'protocol' => 'desfire',
'allow_on_multiple_devices' => true,
'watch_count' => 2,
'iphone_count' => 3,
'design' => [
'background_color' => '#FFFFFF',
'label_color' => '#000000',
'label_secondary_color' => '#333333',
'background_image' => '[image_in_base64_encoded_format]',
'logo_image' => '[image_in_base64_encoded_format]',
'icon_image' => '[image_in_base64_encoded_format]'
],
'support_info' => [
'support_url' => 'https://help.yourcompany.com',
'support_phone_number' => '+1-555-123-4567',
'support_email' => '[email protected]',
'privacy_policy_url' => 'https://yourcompany.com/privacy',
'terms_and_conditions_url' => 'https://yourcompany.com/terms'
],
'metadata' => [
'version' => '2.1',
'approval_status' => 'approved'
]
]);
echo "Template created successfully: {$template->id}\n";
Response
{
"id": "tpl_0xd3adb00b5",
"estimated_publishing_date": "2026-01-05T12:00:00Z",
"metadata": {
"version": "2.1",
"approvalStatus": "approved"
}
}
Update Card Template
Only available for enterprise customers - allows you to update certain attributes of an existing card template using our console API.
card_template_id
string
The card template id you want to update
name
string
The name to display for this card template in the AccessGrid console UI
allow_on_multiple_devices
nullable boolean
False by default. Set to true if you'd like to enable the Access Passes issued using this template to exist on multiple devices (think phone and watch)
watch_count
nullable integer
Only allowed to be set if `allow_on_multiple_devices` is set to true. Any number between 1-5 is acceptable.
iphone_count
nullable integer
Only allowed to be set if `allow_on_multiple_devices` is set to true. Any number between 1-5 is acceptable.
support_info
nullable object
Information for users that shows up on the back of the Access Pass
support_url
nullable string
Shows on the back of the issued Access Pass.
support_phone_number
nullable string
Shows on the back of the issued Access Pass.
support_email
nullable string
Shows on the back of the issued Access Pass.
privacy_policy_url
nullable string
Shows on the back of the issued Access Pass.
terms_and_conditions_url
nullable string
Shows on the back of the issued Access Pass.
metadata
nullable object
Custom JSON object for storing additional metadata associated with the pass template. Can contain any valid JSON data.
Request
curl -v \
-X PATCH \
-H 'X-ACCT-ID: 123' \
-H "X-PAYLOAD-SIG: $HASH" \
-d '{
"card_template_id": "0xd3adb00b5",
"name": "Updated Employee Access Pass",
"allow_on_multiple_devices": true,
"watch_count": 2,
"iphone_count": 3,
"support_info": {
"support_url": "https://help.yourcompany.com",
"support_phone_number": "+1-555-123-4567",
"support_email": "[email protected]",
"privacy_policy_url": "https://yourcompany.com/privacy",
"terms_and_conditions_url": "https://yourcompany.com/terms"
},
"metadata": {
"version": "2.2",
"last_updated_by": "admin"
}
}' \
"https://api.accessgrid.com/v1/console/card-templates/{template_id}"
require 'accessgrid'
acct_id = ENV['ACCOUNT_ID']
secret_key = ENV['SECRET_KEY']
client = AccessGrid.new(acct_id, secret_key)
template = client.console.update_template(
card_template_id: "0xd3adb00b5",
name: "Updated Employee Access Pass",
allow_on_multiple_devices: true,
watch_count: 2,
iphone_count: 3,
support_info: {
support_url: "https://help.yourcompany.com",
support_phone_number: "+1-555-123-4567",
support_email: "[email protected]",
privacy_policy_url: "https://yourcompany.com/privacy",
terms_and_conditions_url: "https://yourcompany.com/terms"
},
metadata: {
version: "2.2",
last_updated_by: "admin"
}
)
puts "Template updated successfully: #{template.id}"
import AccessGrid from 'accessgrid';
const accountId = process.env.ACCOUNT_ID;
const secretKey = process.env.SECRET_KEY;
const client = new AccessGrid(accountId, secretKey);
const updateTemplate = async () => {
try {
const template = await client.console.updateTemplate({
cardTemplateId: "0xd3adb00b5",
name: "Updated Employee Access Pass",
allowOnMultipleDevices: true,
watchCount: 2,
iphoneCount: 3,
supportInfo: {
supportUrl: "https://help.yourcompany.com",
supportPhoneNumber: "+1-555-123-4567",
supportEmail: "[email protected]",
privacyPolicyUrl: "https://yourcompany.com/privacy",
termsAndConditionsUrl: "https://yourcompany.com/terms"
},
metadata: {
version: "2.2",
lastUpdatedBy: "admin"
}
});
console.log(`Template updated successfully: ${template.id}`);
} catch (error) {
console.error('Error updating template:', error);
}
};
updateTemplate();
from accessgrid import AccessGrid
import os
account_id = os.getenv('ACCOUNT_ID')
secret_key = os.getenv('SECRET_KEY')
client = AccessGrid(account_id, secret_key)
template = client.console.update_template(
card_template_id="0xd3adb00b5",
name="Updated Employee Access Pass",
allow_on_multiple_devices=True,
watch_count=2,
iphone_count=3,
support_info={
"support_url": "https://help.yourcompany.com",
"support_phone_number": "+1-555-123-4567",
"support_email": "[email protected]",
"privacy_policy_url": "https://yourcompany.com/privacy",
"terms_and_conditions_url": "https://yourcompany.com/terms"
},
metadata={
"version": "2.2",
"last_updated_by": "admin"
}
)
print(f"Template updated successfully: {template.id}")
package main
import (
"fmt"
"os"
"github.com/accessgrid/accessgrid-go"
)
func main() {
accountID := os.Getenv("ACCOUNT_ID")
secretKey := os.Getenv("SECRET_KEY")
client, err := accessgrid.NewClient(accountID, secretKey)
if err != nil {
fmt.Printf("Error creating client: %v\n", err)
return
}
supportInfo := accessgrid.SupportInfo{
SupportURL: "https://help.yourcompany.com",
SupportPhoneNumber: "+1-555-123-4567",
SupportEmail: "[email protected]",
PrivacyPolicyURL: "https://yourcompany.com/privacy",
TermsAndConditionsURL: "https://yourcompany.com/terms",
}
params := accessgrid.UpdateTemplateParams{
CardTemplateID: "0xd3adb00b5",
Name: "Updated Employee Access Pass",
AllowOnMultipleDevices: true,
WatchCount: 2,
IPhoneCount: 3,
SupportInfo: supportInfo,
}
template, err := client.Console.UpdateTemplate(params)
if err != nil {
fmt.Printf("Error updating template: %v\n", err)
return
}
fmt.Printf("Template updated successfully: %s\n", template.ID)
}
using AccessGrid;
public async Task UpdateTemplateAsync()
{
var accountId = Environment.GetEnvironmentVariable("ACCOUNT_ID");
var secretKey = Environment.GetEnvironmentVariable("SECRET_KEY");
var client = new AccessGridClient(accountId, secretKey);
var template = await client.Console.UpdateTemplateAsync(
new UpdateTemplateRequest
{
CardTemplateId = "0xd3adb00b5",
Name = "Updated Employee Access Pass",
AllowOnMultipleDevices = true,
WatchCount = 2,
IPhoneCount = 3,
SupportInfo = new SupportInfo
{
SupportUrl = "https://help.yourcompany.com",
SupportPhoneNumber = "+1-555-123-4567",
SupportEmail = "[email protected]",
PrivacyPolicyUrl = "https://yourcompany.com/privacy",
TermsAndConditionsUrl = "https://yourcompany.com/terms"
}
}
);
Console.WriteLine($"Template updated successfully: {template.Id}");
}
import com.organization.accessgrid.AccessGridClient;
import com.organization.accessgrid.model.UpdateTemplateRequest;
import com.organization.accessgrid.model.Template;
import com.organization.accessgrid.model.SupportInfo;
public class ConsoleService {
private final AccessGridClient client;
public ConsoleService() {
String accountId = System.getenv("ACCOUNT_ID");
String secretKey = System.getenv("SECRET_KEY");
this.client = new AccessGridClient(accountId, secretKey);
}
public Template updateTemplate() throws AccessGridException {
SupportInfo supportInfo = SupportInfo.builder()
.supportUrl("https://help.yourcompany.com")
.supportPhoneNumber("+1-555-123-4567")
.supportEmail("[email protected]")
.privacyPolicyUrl("https://yourcompany.com/privacy")
.termsAndConditionsUrl("https://yourcompany.com/terms")
.build();
UpdateTemplateRequest request = UpdateTemplateRequest.builder()
.cardTemplateId("0xd3adb00b5")
.name("Updated Employee Access Pass")
.allowOnMultipleDevices(true)
.watchCount(2)
.iphoneCount(3)
.supportInfo(supportInfo)
.build();
Template template = client.console().updateTemplate(request);
System.out.printf("Template updated successfully: %s%n", template.getId());
return template;
}
}
<?php
require 'vendor/autoload.php';
use AccessGridClient;
$accountId = $_ENV['ACCOUNT_ID'];
$secretKey = $_ENV['SECRET_KEY'];
$client = new Client($accountId, $secretKey);
$template = $client->console->updateTemplate([
'card_template_id' => '0xd3adb00b5',
'name' => 'Updated Employee Access Pass',
'allow_on_multiple_devices' => true,
'watch_count' => 2,
'iphone_count' => 3,
'support_info' => [
'support_url' => 'https://help.yourcompany.com',
'support_phone_number' => '+1-555-123-4567',
'support_email' => '[email protected]',
'privacy_policy_url' => 'https://yourcompany.com/privacy',
'terms_and_conditions_url' => 'https://yourcompany.com/terms'
],
'metadata' => [
'version' => '2.2',
'last_updated_by' => 'admin'
]
]);
echo "Template updated successfully: {$template->id}\n";
Response
{
"id": "tpl_0xd3adb00b5",
"estimated_publishing_date": "2026-01-05T12:00:00Z",
"metadata": {
"version": "2.1",
"approvalStatus": "approved"
}
}
Read Card Template
Only available for enterprise customers - allows you to read basic info about an existing card template using our console API.
card_template_id
nullable string
Unique identifier for the card template to look up
Request
curl -v \
-X GET \
-H 'X-ACCT-ID: 123' \
-H "X-PAYLOAD-SIG: $HASH" \
"https://api.accessgrid.com/v1/console/card-templates/{template_id}"
require 'accessgrid'
acct_id = ENV['ACCOUNT_ID']
secret_key = ENV['SECRET_KEY']
client = AccessGrid.new(acct_id, secret_key)
template = client.console.read_template(
card_template_id: "0xd3adb00b5"
)
puts "Template ID: #{template.id}"
puts "Name: #{template.name}"
puts "Platform: #{template.platform}"
puts "Protocol: #{template.protocol}"
puts "Multi-device: #{template.allow_on_multiple_devices}"
import AccessGrid from 'accessgrid';
const accountId = process.env.ACCOUNT_ID;
const secretKey = process.env.SECRET_KEY;
const client = new AccessGrid(accountId, secretKey);
const readTemplate = async () => {
try {
const template = await client.console.readTemplate({
cardTemplateId: "0xd3adb00b5"
});
console.log(`Template ID: ${template.id}`);
console.log(`Name: ${template.name}`);
console.log(`Platform: ${template.platform}`);
console.log(`Protocol: ${template.protocol}`);
console.log(`Multi-device: ${template.allowOnMultipleDevices}`);
} catch (error) {
console.error('Error reading template:', error);
}
};
readTemplate();
from accessgrid import AccessGrid
import os
account_id = os.getenv('ACCOUNT_ID')
secret_key = os.getenv('SECRET_KEY')
client = AccessGrid(account_id, secret_key)
template = client.console.read_template(
card_template_id="0xd3adb00b5"
)
print(f"Template ID: {template.id}")
print(f"Name: {template.name}")
print(f"Platform: {template.platform}")
print(f"Protocol: {template.protocol}")
print(f"Multi-device: {template.allow_on_multiple_devices}")
package main
import (
"fmt"
"os"
"github.com/accessgrid/accessgrid-go"
)
func main() {
accountID := os.Getenv("ACCOUNT_ID")
secretKey := os.Getenv("SECRET_KEY")
client, err := accessgrid.NewClient(accountID, secretKey)
if err != nil {
fmt.Printf("Error creating client: %v\n", err)
return
}
template, err := client.Console.ReadTemplate("0xd3adb00b5")
if err != nil {
fmt.Printf("Error reading template: %v\n", err)
return
}
fmt.Printf("Template ID: %s\n", template.ID)
fmt.Printf("Name: %s\n", template.Name)
fmt.Printf("Platform: %s\n", template.Platform)
fmt.Printf("Protocol: %s\n", template.Protocol)
fmt.Printf("Multi-device: %v\n", template.AllowOnMultipleDevices)
}
using AccessGrid;
public async Task ReadTemplateAsync()
{
var accountId = Environment.GetEnvironmentVariable("ACCOUNT_ID");
var secretKey = Environment.GetEnvironmentVariable("SECRET_KEY");
var client = new AccessGridClient(accountId, secretKey);
var template = await client.Console.ReadTemplateAsync("0xd3adb00b5");
Console.WriteLine($"Template ID: {template.Id}");
Console.WriteLine($"Name: {template.Name}");
Console.WriteLine($"Platform: {template.Platform}");
Console.WriteLine($"Protocol: {template.Protocol}");
Console.WriteLine($"Multi-device: {template.AllowOnMultipleDevices}");
}
import com.organization.accessgrid.AccessGridClient;
import com.organization.accessgrid.model.Template;
public class ConsoleService {
private final AccessGridClient client;
public ConsoleService() {
String accountId = System.getenv("ACCOUNT_ID");
String secretKey = System.getenv("SECRET_KEY");
this.client = new AccessGridClient(accountId, secretKey);
}
public void readTemplate() throws AccessGridException {
Template template = client.console().readTemplate("0xd3adb00b5");
System.out.printf("Template ID: %s%n", template.getId());
System.out.printf("Name: %s%n", template.getName());
System.out.printf("Platform: %s%n", template.getPlatform());
System.out.printf("Protocol: %s%n", template.getProtocol());
System.out.printf("Multi-device: %b%n", template.getAllowOnMultipleDevices());
}
}
<?php
require 'vendor/autoload.php';
use AccessGridClient;
$accountId = $_ENV['ACCOUNT_ID'];
$secretKey = $_ENV['SECRET_KEY'];
$client = new Client($accountId, $secretKey);
$template = $client->console->readTemplate([
'card_template_id' => '0xd3adb00b5'
]);
echo "Template ID: {$template->id}\n";
echo "Name: {$template->name}\n";
echo "Platform: {$template->platform}\n";
echo "Protocol: {$template->protocol}\n";
echo "Multi-device: {$template->allow_on_multiple_devices}\n";
Response
{
"id": "tpl_0xd3adb00b5",
"name": "Employee Access Pass",
"platform": "apple",
"use_case": "employee_badge",
"protocol": "desfire",
"created_at": "2025-12-01T09:15:30Z",
"last_published_at": "2025-12-10T14:42:00Z",
"issued_keys_count": 125,
"active_keys_count": 118,
"allowed_device_counts": {
"allow_on_multiple_devices": true,
"watch": 2,
"iphone": 3
},
"support_settings": {
"url": "https://help.yourcompany.com",
"phone": "+1-555-123-4567",
"email": "[email protected]"
},
"terms_settings": {
"privacy_policy_url": "https://yourcompany.com/privacy",
"terms_and_conditions_url": "https://yourcompany.com/terms"
},
"style_settings": {
"background_color": "#FFFFFF",
"label_color": "#000000",
"label_secondary_color": "#333333"
},
"metadata": {
"version": "2.1",
"approvalStatus": "approved"
}
}
Read Event Log
Only available for enterprise customers - allows you to read full event log for a given card template, including which passes were issued, how and by whom using our console API.
card_template_id
nullable string
Unique identifier for the card template to look up
filters
nullable object
Filters to reduce result size of event logs
device
nullable string
Must be either `mobile` or `watch`
start_date
nullable datetime
Must be in ISO8601 format
end_date
nullable datetime
Must be in ISO8601 format
event_type
nullable string
Must be either `issue`, `install`, `update`, `suspend`, `resume`, or `unlink`
Request
curl -v \
-X GET \
-H 'X-ACCT-ID: 123' \
-H "X-PAYLOAD-SIG: $HASH" \
"https://api.accessgrid.com/v1/console/card-templates/{template_id}/logs"
require 'accessgrid'
acct_id = ENV['ACCOUNT_ID']
secret_key = ENV['SECRET_KEY']
client = AccessGrid.new(acct_id, secret_key)
events = client.console.event_log(
card_template_id: "0xd3adb00b5",
filters: {
device: "mobile",
start_date: "2025-12-15T11:04:10.556Z",
end_date: "2026-01-14T11:04:10.556Z",
event_type: "install"
}
)
events.each do |event|
puts "Event: #{event.type} at #{event.timestamp} by #{event.user_id}"
end
import AccessGrid from 'accessgrid';
const accountId = process.env.ACCOUNT_ID;
const secretKey = process.env.SECRET_KEY;
const client = new AccessGrid(accountId, secretKey);
const getEventLog = async () => {
try {
const events = await client.console.eventLog({
cardTemplateId: "0xd3adb00b5",
filters: {
device: "mobile",
startDate: new Date(Date.now() - 30 * 24 * 60 * 60 * 1000).toISOString(),
endDate: new Date().toISOString(),
eventType: "install"
}
});
events.forEach(event => {
console.log(`Event: ${event.type} at ${event.timestamp} by ${event.userId}`);
});
} catch (error) {
console.error('Error fetching event log:', error);
}
};
getEventLog();
from accessgrid import AccessGrid
import os
from datetime import datetime, timezone, timedelta
account_id = os.getenv('ACCOUNT_ID')
secret_key = os.getenv('SECRET_KEY')
client = AccessGrid(account_id, secret_key)
start_date = (datetime.now(timezone.utc) - timedelta(days=30)).isoformat()
end_date = datetime.now(timezone.utc).isoformat()
events = client.console.event_log(
card_template_id="0xd3adb00b5",
filters={
"device": "mobile",
"start_date": start_date,
"end_date": end_date,
"event_type": "install"
}
)
for event in events:
print(f"Event: {event.type} at {event.timestamp} by {event.user_id}")
package main
import (
"fmt"
"os"
"time"
"github.com/accessgrid/accessgrid-go"
)
func main() {
accountID := os.Getenv("ACCOUNT_ID")
secretKey := os.Getenv("SECRET_KEY")
client, err := accessgrid.NewClient(accountID, secretKey)
if err != nil {
fmt.Printf("Error creating client: %v\n", err)
return
}
filters := accessgrid.EventLogFilters{
Device: "mobile",
StartDate: time.Now().AddDate(0, 0, -30).UTC().Format(time.RFC3339),
EndDate: time.Now().UTC().Format(time.RFC3339),
EventType: "install",
}
events, err := client.Console.EventLog("0xd3adb00b5", filters)
if err != nil {
fmt.Printf("Error fetching event log: %v\n", err)
return
}
for _, event := range events {
fmt.Printf("Event: %s at %s by %s\n", event.Type, event.Timestamp, event.UserID)
}
}
using AccessGrid;
using System;
public async Task GetEventLogAsync()
{
var accountId = Environment.GetEnvironmentVariable("ACCOUNT_ID");
var secretKey = Environment.GetEnvironmentVariable("SECRET_KEY");
var client = new AccessGridClient(accountId, secretKey);
var events = await client.Console.EventLogAsync(
"0xd3adb00b5",
new EventLogFilters
{
Device = "mobile",
StartDate = DateTime.UtcNow.AddDays(-30),
EndDate = DateTime.UtcNow,
EventType = "install"
});
foreach (var evt in events)
{
Console.WriteLine($"Event: {evt.Type} at {evt.Timestamp} by {evt.UserId}");
}
}
import com.organization.accessgrid.AccessGridClient;
import com.organization.accessgrid.model.Event;
import com.organization.accessgrid.model.EventLogFilters;
import java.time.ZonedDateTime;
import java.util.List;
public class ConsoleService {
private final AccessGridClient client;
public ConsoleService() {
String accountId = System.getenv("ACCOUNT_ID");
String secretKey = System.getenv("SECRET_KEY");
this.client = new AccessGridClient(accountId, secretKey);
}
public void getEventLog() throws AccessGridException {
EventLogFilters filters = EventLogFilters.builder()
.device("mobile")
.startDate(ZonedDateTime.now().minusDays(30))
.endDate(ZonedDateTime.now())
.eventType("install")
.build();
List<Event> events = client.console().eventLog("0xd3adb00b5", filters);
for (Event event : events) {
System.out.printf("Event: %s at %s by %s%n",
event.getType(),
event.getTimestamp(),
event.getUserId());
}
}
}
<?php
require 'vendor/autoload.php';
use AccessGridClient;
$accountId = $_ENV['ACCOUNT_ID'];
$secretKey = $_ENV['SECRET_KEY'];
$client = new Client($accountId, $secretKey);
$events = $client->console->eventLog([
'card_template_id' => '0xd3adb00b5',
'filters' => [
'device' => 'mobile',
'start_date' => (new DateTime('30 days ago'))->format('c'),
'end_date' => (new DateTime('now'))->format('c'),
'event_type' => 'install'
]
]);
foreach ($events as $event) {
echo "Event: {$event->type} at {$event->timestamp} by {$event->user_id}\n";
}
Response
{
"logs": [
{
"id": "evt_91f2a7c3",
"event": "install",
"created_at": "2025-11-30T10:14:22Z",
"ip_address": "192.168.1.24",
"user_agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_1 like Mac OS X)",
"metadata": {
"device": "mobile",
"platform": "ios",
"card_id": "key_a91c7e23",
"template_id": "0xd3adb00b5"
}
},
{
"id": "evt_c83d19aa",
"event": "install",
"created_at": "2025-12-05T16:48:09Z",
"ip_address": "10.0.0.88",
"user_agent": "Mozilla/5.0 (Linux; Android 14; Pixel 8)",
"metadata": {
"device": "mobile",
"platform": "android",
"card_id": "key_b81d77ef",
"template_id": "0xd3adb00b5"
}
}
],
"pagination": {
"current_page": 1,
"per_page": 20,
"total_pages": 1,
"total_count": 2
}
}
iOS Preflight
Only available for enterprise customers - provides the required identifiers for iOS mobile provisioning for an access pass associated with a given card template.
card_template_id
string
The card template ID (ex_id) the access pass belongs to
access_pass_ex_id
string
The ex_id of the access pass to retrieve provisioning identifiers for
Request
curl -v \
-X POST \
-H 'X-ACCT-ID: 123' \
-H "X-PAYLOAD-SIG: $HASH" \
-d '{
"access_pass_ex_id": "0xp455-3x1d"
}' \
"https://api.accessgrid.com/v1/console/card-templates/0xt3mp14t3-3x1d/ios_preflight"
require 'accessgrid'
acct_id = ENV['ACCOUNT_ID']
secret_key = ENV['SECRET_KEY']
client = AccessGrid.new(acct_id, secret_key)
response = client.console.ios_preflight(
card_template_id: "0xt3mp14t3-3x1d",
access_pass_ex_id: "0xp455-3x1d"
)
puts "Provisioning Credential ID: #{response.provisioningCredentialIdentifier}"
puts "Sharing Instance ID: #{response.sharingInstanceIdentifier}"
puts "Card Template ID: #{response.cardTemplateIdentifier}"
puts "Environment ID: #{response.environmentIdentifier}"
import AccessGrid from 'accessgrid';
const accountId = process.env.ACCOUNT_ID;
const secretKey = process.env.SECRET_KEY;
const client = new AccessGrid(accountId, secretKey);
const getProvisioningIdentifiers = async () => {
try {
const response = await client.console.iosPreflight({
cardTemplateId: "0xt3mp14t3-3x1d",
accessPassExId: "0xp455-3x1d"
});
console.log(`Provisioning Credential ID: ${response.provisioningCredentialIdentifier}`);
console.log(`Sharing Instance ID: ${response.sharingInstanceIdentifier}`);
console.log(`Card Template ID: ${response.cardTemplateIdentifier}`);
console.log(`Environment ID: ${response.environmentIdentifier}`);
} catch (error) {
console.error('Error retrieving provisioning identifiers:', error);
}
};
getProvisioningIdentifiers();
from accessgrid import AccessGrid
import os
account_id = os.getenv('ACCOUNT_ID')
secret_key = os.getenv('SECRET_KEY')
client = AccessGrid(account_id, secret_key)
response = client.console.ios_preflight(
card_template_id="0xt3mp14t3-3x1d",
access_pass_ex_id="0xp455-3x1d"
)
print(f"Provisioning Credential ID: {response.provisioningCredentialIdentifier}")
print(f"Sharing Instance ID: {response.sharingInstanceIdentifier}")
print(f"Card Template ID: {response.cardTemplateIdentifier}")
print(f"Environment ID: {response.environmentIdentifier}")
using AccessGrid;
using System;
using System.Threading.Tasks;
public async Task GenerateProvisioningCredentialsAsync()
{
var client = new AccessGridClient(
Environment.GetEnvironmentVariable(\"ACCOUNT_ID\"),
Environment.GetEnvironmentVariable(\"SECRET_KEY\")
);
var response = await client.Console.IosPreflightAsync(
cardTemplateId: "0xt3mp14t3-3x1d",
accessPassExId: "0xp455-3x1d"
);
Console.WriteLine($\"Provisioning Credential ID: {response.ProvisioningCredentialIdentifier}\");
Console.WriteLine($\"Sharing Instance ID: {response.SharingInstanceIdentifier}\");
Console.WriteLine($\"Card Template ID: {response.CardTemplateIdentifier}\");
Console.WriteLine($\"Environment ID: {response.EnvironmentIdentifier}\");
}
<?php
require 'vendor/autoload.php';
$accountId = getenv('ACCOUNT_ID');
$secretKey = getenv('SECRET_KEY');
$client = new AccessGrid\Client($accountId, $secretKey);
try {
$response = $client->console->iosPreflight([
'card_template_id' => '0xt3mp14t3-3x1d',
'access_pass_ex_id' => '0xp455-3x1d'
]);
echo \"Provisioning Credential ID: \" . $response->provisioningCredentialIdentifier . \"\\n\";
echo \"Sharing Instance ID: \" . $response->sharingInstanceIdentifier . \"\\n\";
echo \"Card Template ID: \" . $response->cardTemplateIdentifier . \"\\n\";
echo \"Environment ID: \" . $response->environmentIdentifier . \"\\n\";
} catch (Exception $e) {
echo \"Error retrieving provisioning identifiers: \" . $e->getMessage() . \"\\n\";
}
Response
{
"provisioningCredentialIdentifier": "apple_cred_8f3c2a91",
"sharingInstanceIdentifier": "apple_share_41d9be77",
"cardTemplateIdentifier": "apple_tpl_a12bc9ef",
"environmentIdentifier": "apple_access_env_production"
}
Webhooks
AccessGrid can send webhook notifications to your server when events occur. Webhooks use the CloudEvents specification for event delivery.
Configure webhooks in your AccessGrid console.
We use simple bearer tokens for authentication, which is generated whenever you create a new webhook. In general if your server responds with either 200, or 201, then we will not send the event occurrence again.
If we cannot reach your server, or you respond with non 200/201 response code, we will try again for up to 6 hours before dropping the delivery attempts.
spec_version
string
CloudEvents specification version (always "1.0")
id
string
Unique identifier for this event
source
string
Event source (always "accessgrid")
type
string
Event type. Possible values:
Access Pass:
ag.access_pass.issued
ag.access_pass.activated
ag.access_pass.updated
ag.access_pass.suspended
ag.access_pass.resumed
ag.access_pass.unlinked
ag.access_pass.deleted
ag.access_pass.expired
Card Template:
ag.card_template.created
ag.card_template.updated
ag.card_template.requested_publishing
ag.card_template.published
Landing Page:
ag.landing_page.created
ag.landing_page.updated
ag.landing_page.attached_to_template
Credential Profile:
ag.credential_profile.created
ag.credential_profile.attached_to_template
HID Org
ag.hid_org.created
ag.hid_org.activated
Account Balance:
ag.account_balance.low
data_content_type
string
Content type of the data payload (always "application/json")
time
string
ISO 8601 timestamp when the event occurred
data
object
Event-specific data payload
access_pass_id
nullable string
ID of the access pass (for access_pass events)
card_template_id
nullable string
ID of the card template (for card_template events)
landing_page_id
nullable string
ID of the landing page (for landing_page events)
credential_profile_id
nullable string
ID of the credential profile (for credential_profile events)
account_id
nullable string
API ID of the account (for account_balance events)
organization_name
nullable string
Name of the organization (for account_balance events)
current_balance
nullable number
Current balance in dollars (for account_balance events)
threshold
nullable number
Low balance threshold in dollars (for account_balance events)
amount_below_threshold
nullable number
How far below threshold the balance is in dollars (for account_balance events)
protocol
nullable string
Protocol type (desfire, seos, smart_tap)
metadata
nullable object
Custom metadata associated with the resource
device
nullable object
Device information (for access_pass device events)
Request
# Example webhook payload (CloudEvents format)
# This is what AccessGrid will POST to your webhook URL
# Example: Access Pass Issued Event
{
"specversion": "1.0",
"id": "unique-event-id-12345",
"source": "accessgrid",
"type": "ag.access_pass.issued",
"datacontenttype": "application/json",
"time": "2025-01-15T10:30:00Z",
"data": {
"access_pass_id": "0xp455-3x1d",
"protocol": "desfire",
"metadata": {
"custom_field": "value"
}
}
}
# Example: Card Template Published Event
{
"specversion": "1.0",
"id": "unique-event-id-67890",
"source": "accessgrid",
"type": "ag.card_template.published",
"datacontenttype": "application/json",
"time": "2025-01-15T11:00:00Z",
"data": {
"card_template_id": "0xt3mp14t3-3x1d",
"protocol": "seos",
"metadata": {}
}
}
# Verify webhook with your endpoint
curl -X POST https://your-server.com/webhooks \
-H "Content-Type: application/cloudevents+json" \
-H "User-Agent: AccessGrid-Webhooks/1.0" \
-d '{
"specversion": "1.0",
"id": "test-event-123",
"source": "accessgrid",
"type": "ag.access_pass.activated",
"datacontenttype": "application/json",
"time": "2025-01-15T12:00:00Z",
"data": {
"access_pass_id": "0xp455-3x1d",
"protocol": "desfire",
"device": {
"type": "iphone",
"id": "device-hash-id"
}
}
}'
require 'sinatra'
require 'json'
# Webhook endpoint to receive AccessGrid events
post '/webhooks' do
request.body.rewind
payload = JSON.parse(request.body.read)
# Verify it's a CloudEvents payload
unless payload['specversion'] == '1.0'
halt 400, { error: 'Invalid CloudEvents format' }.to_json
end
# Handle different event types
case payload['type']
when 'ag.access_pass.issued'
handle_access_pass_issued(payload['data'])
when 'ag.access_pass.activated'
handle_access_pass_activated(payload['data'])
when 'ag.card_template.published'
handle_template_published(payload['data'])
else
puts "Unknown event type: #{payload['type']}"
end
# Always return 200 to acknowledge receipt
status 200
{ received: true }.to_json
end
def handle_access_pass_issued(data)
puts "Access pass issued: #{data['access_pass_id']}"
# Your custom logic here
end
def handle_access_pass_activated(data)
puts "Access pass activated: #{data['access_pass_id']}"
puts "Device: #{data['device']['type']}"
# Your custom logic here
end
def handle_template_published(data)
puts "Template published: #{data['card_template_id']}"
# Your custom logic here
end
const express = require('express');
const app = express();
app.use(express.json({
type: ['application/json', 'application/cloudevents+json']
}));
// Webhook endpoint to receive AccessGrid events
app.post('/webhooks', (req, res) => {
const payload = req.body;
// Verify it's a CloudEvents payload
if (payload.specversion !== '1.0') {
return res.status(400).json({ error: 'Invalid CloudEvents format' });
}
// Handle different event types
switch (payload.type) {
case 'ag.access_pass.issued':
handleAccessPassIssued(payload.data);
break;
case 'ag.access_pass.activated':
handleAccessPassActivated(payload.data);
break;
case 'ag.card_template.published':
handleTemplatePublished(payload.data);
break;
default:
console.log(`Unknown event type: ${payload.type}`);
}
// Always return 200 to acknowledge receipt
res.status(200).json({ received: true });
});
function handleAccessPassIssued(data) {
console.log(`Access pass issued: ${data.access_pass_id}`);
// Your custom logic here
}
function handleAccessPassActivated(data) {
console.log(`Access pass activated: ${data.access_pass_id}`);
console.log(`Device: ${data.device.type}`);
// Your custom logic here
}
function handleTemplatePublished(data) {
console.log(`Template published: ${data.card_template_id}`);
// Your custom logic here
}
app.listen(3000, () => {
console.log('Webhook server listening on port 3000');
});
from flask import Flask, request, jsonify
app = Flask(__name__)
@app.route('/webhooks', methods=['POST'])
def webhook():
payload = request.get_json()
# Verify it's a CloudEvents payload
if payload.get('specversion') != '1.0':
return jsonify({'error': 'Invalid CloudEvents format'}), 400
# Handle different event types
event_type = payload.get('type')
data = payload.get('data', {})
if event_type == 'ag.access_pass.issued':
handle_access_pass_issued(data)
elif event_type == 'ag.access_pass.activated':
handle_access_pass_activated(data)
elif event_type == 'ag.card_template.published':
handle_template_published(data)
else:
print(f"Unknown event type: {event_type}")
# Always return 200 to acknowledge receipt
return jsonify({'received': True}), 200
def handle_access_pass_issued(data):
print(f"Access pass issued: {data['access_pass_id']}")
# Your custom logic here
def handle_access_pass_activated(data):
print(f"Access pass activated: {data['access_pass_id']}")
print(f"Device: {data['device']['type']}")
# Your custom logic here
def handle_template_published(data):
print(f"Template published: {data['card_template_id']}")
# Your custom logic here
if __name__ == '__main__':
app.run(port=3000)
package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
)
type CloudEvent struct {
SpecVersion string `json:\"specversion\"`
ID string `json:\"id\"`
Source string `json:\"source\"`
Type string `json:\"type\"`
Time string `json:\"time\"`
Data map[string]interface{} `json:\"data\"`
}
func webhookHandler(w http.ResponseWriter, r *http.Request) {
var event CloudEvent
if err := json.NewDecoder(r.Body).Decode(&event); err != nil {
http.Error(w, "Invalid JSON", http.StatusBadRequest)
return
}
// Verify it's a CloudEvents payload
if event.SpecVersion != "1.0" {
http.Error(w, "Invalid CloudEvents format", http.StatusBadRequest)
return
}
// Handle different event types
switch event.Type {
case "ag.access_pass.issued":
handleAccessPassIssued(event.Data)
case "ag.access_pass.activated":
handleAccessPassActivated(event.Data)
case "ag.card_template.published":
handleTemplatePublished(event.Data)
default:
log.Printf("Unknown event type: %s", event.Type)
}
// Always return 200 to acknowledge receipt
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(map[string]bool{"received": true})
}
func handleAccessPassIssued(data map[string]interface{}) {
fmt.Printf("Access pass issued: %v\\n", data["access_pass_id"])
// Your custom logic here
}
func handleAccessPassActivated(data map[string]interface{}) {
fmt.Printf("Access pass activated: %v\\n", data["access_pass_id"])
if device, ok := data["device"].(map[string]interface{}); ok {
fmt.Printf("Device: %v\\n", device["type"])
}
// Your custom logic here
}
func handleTemplatePublished(data map[string]interface{}) {
fmt.Printf("Template published: %v\\n", data["card_template_id"])
// Your custom logic here
}
func main() {
http.HandleFunc("/webhooks", webhookHandler)
log.Println("Webhook server listening on port 3000")
log.Fatal(http.ListenAndServe(":3000", nil))
}
using System;
using System.IO;
using System.Text.Json;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapPost(\"/webhooks\", async (HttpContext context) =>
{
using var reader = new StreamReader(context.Request.Body);
var body = await reader.ReadToEndAsync();
var payload = JsonSerializer.Deserialize<CloudEvent>(body);
// Verify it's a CloudEvents payload
if (payload?.SpecVersion != \"1.0\")
{
context.Response.StatusCode = 400;
await context.Response.WriteAsJsonAsync(new { error = \"Invalid CloudEvents format\" });
return;
}
// Handle different event types
switch (payload.Type)
{
case \"ag.access_pass.issued\":
HandleAccessPassIssued(payload.Data);
break;
case \"ag.access_pass.activated\":
HandleAccessPassActivated(payload.Data);
break;
case \"ag.card_template.published\":
HandleTemplatePublished(payload.Data);
break;
default:
Console.WriteLine($\"Unknown event type: {payload.Type}\");
break;
}
// Always return 200 to acknowledge receipt
await context.Response.WriteAsJsonAsync(new { received = true });
});
void HandleAccessPassIssued(JsonElement data)
{
Console.WriteLine($\"Access pass issued: {data.GetProperty(\\\"access_pass_id\\\").GetString()}\");
// Your custom logic here
}
void HandleAccessPassActivated(JsonElement data)
{
Console.WriteLine($\"Access pass activated: {data.GetProperty(\\\"access_pass_id\\\").GetString()}\");
if (data.TryGetProperty(\"device\", out var device))
{
Console.WriteLine($\"Device: {device.GetProperty(\\\"type\\\").GetString()}\");
}
// Your custom logic here
}
void HandleTemplatePublished(JsonElement data)
{
Console.WriteLine($\"Template published: {data.GetProperty(\\\"card_template_id\\\").GetString()}\");
// Your custom logic here
}
app.Run(\"http://localhost:3000\");
record CloudEvent(string SpecVersion, string Id, string Source, string Type, string Time, JsonElement Data);
import com.sun.net.httpserver.HttpServer;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpExchange;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import java.io.*;
import java.net.InetSocketAddress;
import java.nio.charset.StandardCharsets;
public class WebhookServer {
private static final Gson gson = new Gson();
public static void main(String[] args) throws IOException {
HttpServer server = HttpServer.create(new InetSocketAddress(3000), 0);
server.createContext(\"/webhooks\", new WebhookHandler());
server.start();
System.out.println(\"Webhook server listening on port 3000\");
}
static class WebhookHandler implements HttpHandler {
@Override
public void handle(HttpExchange exchange) throws IOException {
if (!\"POST\".equals(exchange.getRequestMethod())) {
exchange.sendResponseHeaders(405, 0);
exchange.close();
return;
}
InputStream is = exchange.getRequestBody();
String body = new String(is.readAllBytes(), StandardCharsets.UTF_8);
JsonObject payload = gson.fromJson(body, JsonObject.class);
// Verify it's a CloudEvents payload
if (!\"1.0\".equals(payload.get(\"specversion\").getAsString())) {
String response = \"{\\\"error\\\": \\\"Invalid CloudEvents format\\\"}\";
exchange.sendResponseHeaders(400, response.length());
OutputStream os = exchange.getResponseBody();
os.write(response.getBytes());
os.close();
return;
}
// Handle different event types
String type = payload.get(\"type\").getAsString();
JsonObject data = payload.getAsJsonObject(\"data\");
switch (type) {
case \"ag.access_pass.issued\":
handleAccessPassIssued(data);
break;
case \"ag.access_pass.activated\":
handleAccessPassActivated(data);
break;
case \"ag.card_template.published\":
handleTemplatePublished(data);
break;
default:
System.out.println(\"Unknown event type: \" + type);
}
// Always return 200 to acknowledge receipt
String response = \"{\\\"received\\\": true}\";
exchange.sendResponseHeaders(200, response.length());
OutputStream os = exchange.getResponseBody();
os.write(response.getBytes());
os.close();
}
private void handleAccessPassIssued(JsonObject data) {
System.out.println(\"Access pass issued: \" + data.get(\"access_pass_id\").getAsString());
// Your custom logic here
}
private void handleAccessPassActivated(JsonObject data) {
System.out.println(\"Access pass activated: \" + data.get(\"access_pass_id\").getAsString());
if (data.has(\"device\")) {
JsonObject device = data.getAsJsonObject(\"device\");
System.out.println(\"Device: \" + device.get(\"type\").getAsString());
}
// Your custom logic here
}
private void handleTemplatePublished(JsonObject data) {
System.out.println(\"Template published: \" + data.get(\"card_template_id\").getAsString());
// Your custom logic here
}
}
}
<?php
require 'vendor/autoload.php';
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Slim\Factory\AppFactory;
$app = AppFactory::create();
$app->addBodyParsingMiddleware();
$app->post('/webhooks', function (Request $request, Response $response) {
$payload = $request->getParsedBody();
// Verify it's a CloudEvents payload
if (!isset($payload['specversion']) || $payload['specversion'] !== '1.0') {
$response->getBody()->write(json_encode(['error' => 'Invalid CloudEvents format']));
return $response->withStatus(400)->withHeader('Content-Type', 'application/json');
}
// Handle different event types
$type = $payload['type'] ?? '';
$data = $payload['data'] ?? [];
switch ($type) {
case 'ag.access_pass.issued':
handleAccessPassIssued($data);
break;
case 'ag.access_pass.activated':
handleAccessPassActivated($data);
break;
case 'ag.card_template.published':
handleTemplatePublished($data);
break;
default:
error_log(\"Unknown event type: $type\");
}
// Always return 200 to acknowledge receipt
$response->getBody()->write(json_encode(['received' => true]));
return $response->withHeader('Content-Type', 'application/json');
});
function handleAccessPassIssued($data) {
error_log(\"Access pass issued: {$data['access_pass_id']}\");
// Your custom logic here
}
function handleAccessPassActivated($data) {
error_log(\"Access pass activated: {$data['access_pass_id']}\");
if (isset($data['device'])) {
error_log(\"Device: {$data['device']['type']}\");
}
// Your custom logic here
}
function handleTemplatePublished($data) {
error_log(\"Template published: {$data['card_template_id']}\");
// Your custom logic here
}
$app->run();
Response
Empty
Create HID Org
Create a new HID org for your enterprise or partner account. Generates credentials and queues automation to finish HID setup.
name
string
Organization name
full_address
string
Full address
phone
string
Primary phone
first_name
string
Admin first name
last_name
string
Admin last name
Request
curl -X POST \
-H "X-ACCT-ID: $ACCOUNT_ID" \
-H "X-PAYLOAD-SIG: $SIG" \
-H "Content-Type: application/json" \
-d '{"name":"My Org","full_address":"1 Main St, NY NY","phone":"+1-555-0000","first_name":"Ada","last_name":"Lovelace"}' \
https://api.accessgrid.com/v1/console/hid/orgs
require 'accessgrid'
account_id = ENV['ACCOUNT_ID']
secret_key = ENV['SECRET_KEY']
client = AccessGrid::Client.new(account_id, secret_key)
# Create HID org
org = client.console.hid.orgs.create(
name: 'My Org',
full_address: '1 Main St, NY NY',
phone: '+1-555-0000',
first_name: 'Ada',
last_name: 'Lovelace'
)
puts "Created org: #{org.name} (ID: #{org.id})"
puts "Slug: #{org.slug}"
import AccessGrid from 'accessgrid';
const accountId = process.env.ACCOUNT_ID;
const secretKey = process.env.SECRET_KEY;
const client = new AccessGrid(accountId, secretKey);
const createOrg = async () => {
try {
// Create HID org
const org = await client.console.hid.orgs.create({
name: 'My Org',
fullAddress: '1 Main St, NY NY',
phone: '+1-555-0000',
firstName: 'Ada',
lastName: 'Lovelace'
});
console.log(`Created org: ${org.name} (ID: ${org.id})`);
console.log(`Slug: ${org.slug}`);
} catch (error) {
console.error('Error creating HID org:', error);
}
};
createOrg();
from accessgrid import AccessGrid
import os
account_id = os.getenv('ACCOUNT_ID')
secret_key = os.getenv('SECRET_KEY')
client = AccessGrid(account_id, secret_key)
# Create HID org
org = client.console.hid.orgs.create(
name='My Org',
full_address='1 Main St, NY NY',
phone='+1-555-0000',
first_name='Ada',
last_name='Lovelace'
)
print(f"Created org: {org.name} (ID: {org.id})")
print(f"Slug: {org.slug}")
package main
import (
"fmt"
"os"
"github.com/accessgrid/accessgrid-go"
)
func main() {
accountID := os.Getenv("ACCOUNT_ID")
secretKey := os.Getenv("SECRET_KEY")
client, err := accessgrid.NewClient(accountID, secretKey)
if err != nil {
fmt.Printf("Error creating client: %v\n", err)
return
}
// Create HID org
org, err := client.Console.HID.Orgs.Create(&accessgrid.CreateHIDOrgParams{
Name: "My Org",
FullAddress: "1 Main St, NY NY",
Phone: "+1-555-0000",
FirstName: "Ada",
LastName: "Lovelace",
})
if err != nil {
fmt.Printf("Error creating org: %v\n", err)
return
}
fmt.Printf("Created org: %s (ID: %d)\n", org.Name, org.ID)
fmt.Printf("Slug: %s\n", org.Slug)
}
using AccessGrid;
using System;
using System.Threading.Tasks;
public async Task CreateOrgAsync()
{
var accountId = Environment.GetEnvironmentVariable("ACCOUNT_ID");
var secretKey = Environment.GetEnvironmentVariable("SECRET_KEY");
var client = new AccessGridClient(accountId, secretKey);
// Create HID org
var org = await client.Console.HID.Orgs.CreateAsync(new CreateHIDOrgRequest
{
Name = "My Org",
FullAddress = "1 Main St, NY NY",
Phone = "+1-555-0000",
FirstName = "Ada",
LastName = "Lovelace"
});
Console.WriteLine($"Created org: {org.Name} (ID: {org.Id})");
Console.WriteLine($"Slug: {org.Slug}");
}
public class CreateHIDOrgRequest
{
public string Name { get; set; }
public string FullAddress { get; set; }
public string Phone { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
import com.organization.accessgrid.AccessGridClient;
import com.organization.accessgrid.model.HIDOrg;
import com.organization.accessgrid.model.CreateHIDOrgParams;
public class HIDOrgService {
private final AccessGridClient client;
public HIDOrgService() {
String accountId = System.getenv("ACCOUNT_ID");
String secretKey = System.getenv("SECRET_KEY");
this.client = new AccessGridClient(accountId, secretKey);
}
public void createOrg() throws AccessGridException {
// Create HID org
CreateHIDOrgParams params = CreateHIDOrgParams.builder()
.name("My Org")
.fullAddress("1 Main St, NY NY")
.phone("+1-555-0000")
.firstName("Ada")
.lastName("Lovelace")
.build();
HIDOrg org = client.console().hid().orgs().create(params);
System.out.printf("Created org: %s (ID: %d)%n", org.getName(), org.getId());
System.out.printf("Slug: %s%n", org.getSlug());
}
}
Response
[
{
"id": "91c2a7e4f8b",
"name": "Acme Corporation",
"slug": "acme-corp",
"first_name": "John",
"last_name": "Doe",
"phone": "+1-415-555-0198",
"full_address": "123 Market Street, San Francisco, CA 94105, USA",
"status": "active",
"created_at": "2024-08-12T11:32:45Z"
},
{
"id": "b73d9f21a3c",
"name": "Globex Industries",
"slug": "globex-industries",
"first_name": "Jane",
"last_name": "Smith",
"phone": "+1-212-555-7744",
"full_address": "456 Madison Avenue, New York, NY 10022, USA",
"status": "pending",
"created_at": "2025-02-03T09:18:10Z"
}
]
List HID Orgs
List HID orgs created under the current enterprise or partner account.
Request
curl -X GET \
-H "X-ACCT-ID: $ACCOUNT_ID" \
-H "X-PAYLOAD-SIG: $SIG" \
https://api.accessgrid.com/v1/console/hid/orgs
require 'accessgrid'
account_id = ENV['ACCOUNT_ID']
secret_key = ENV['SECRET_KEY']
client = AccessGrid::Client.new(account_id, secret_key)
# List all HID orgs
orgs = client.console.hid.orgs.list
# Print orgs
orgs.each do |org|
puts "Org ID: #{org.id}, Name: #{org.name}, Slug: #{org.slug}"
end
import AccessGrid from 'accessgrid';
const accountId = process.env.ACCOUNT_ID;
const secretKey = process.env.SECRET_KEY;
const client = new AccessGrid(accountId, secretKey);
const listOrgs = async () => {
try {
// List all HID orgs
const orgs = await client.console.hid.orgs.list();
// Print orgs
orgs.forEach(org => {
console.log(`Org ID: ${org.id}, Name: ${org.name}, Slug: ${org.slug}`);
});
} catch (error) {
console.error('Error listing HID orgs:', error);
}
};
listOrgs();
from accessgrid import AccessGrid
import os
account_id = os.getenv('ACCOUNT_ID')
secret_key = os.getenv('SECRET_KEY')
client = AccessGrid(account_id, secret_key)
# List all HID orgs
orgs = client.console.hid.orgs.list()
# Print orgs
for org in orgs:
print(f"Org ID: {org.id}, Name: {org.name}, Slug: {org.slug}")
package main
import (
"fmt"
"os"
"github.com/accessgrid/accessgrid-go"
)
func main() {
accountID := os.Getenv("ACCOUNT_ID")
secretKey := os.Getenv("SECRET_KEY")
client, err := accessgrid.NewClient(accountID, secretKey)
if err != nil {
fmt.Printf("Error creating client: %v\n", err)
return
}
// List all HID orgs
orgs, err := client.Console.HID.Orgs.List()
if err != nil {
fmt.Printf("Error listing orgs: %v\n", err)
return
}
// Print orgs
for _, org := range orgs {
fmt.Printf("Org ID: %d, Name: %s, Slug: %s\n", org.ID, org.Name, org.Slug)
}
}
using AccessGrid;
using System;
using System.Threading.Tasks;
public async Task ListOrgsAsync()
{
var accountId = Environment.GetEnvironmentVariable("ACCOUNT_ID");
var secretKey = Environment.GetEnvironmentVariable("SECRET_KEY");
var client = new AccessGridClient(accountId, secretKey);
// List all HID orgs
var orgs = await client.Console.HID.Orgs.ListAsync();
// Print orgs
foreach (var org in orgs)
{
Console.WriteLine($"Org ID: {org.Id}, Name: {org.Name}, Slug: {org.Slug}");
}
}
import com.organization.accessgrid.AccessGridClient;
import com.organization.accessgrid.model.HIDOrg;
import java.util.List;
public class HIDOrgService {
private final AccessGridClient client;
public HIDOrgService() {
String accountId = System.getenv("ACCOUNT_ID");
String secretKey = System.getenv("SECRET_KEY");
this.client = new AccessGridClient(accountId, secretKey);
}
public void listOrgs() throws AccessGridException {
// List all HID orgs
List<HIDOrg> orgs = client.console().hid().orgs().list();
// Print orgs
for (HIDOrg org : orgs) {
System.out.printf("Org ID: %d, Name: %s, Slug: %s%n",
org.getId(),
org.getName(),
org.getSlug());
}
}
}
Response
Empty
Finish HID Org Registration
Complete the HID org registration process after creating an org. This is a follow-up step to 'Create HID Org' and should be called once you receive the HID registration email with credentials. The email and password are provided by HID during their registration process.
string
Email address from the HID registration email
password
string
Temporary password from the HID registration email
Request
curl -X POST \
-H "X-ACCT-ID: $ACCOUNT_ID" \
-H "X-PAYLOAD-SIG: $SIG" \
-H "Content-Type: application/json" \
-d '{"email":"[email protected]","password":"hid-password-123"}' \
https://api.accessgrid.com/v1/console/hid/orgs/activate
require 'accessgrid'
account_id = ENV['ACCOUNT_ID']
secret_key = ENV['SECRET_KEY']
client = AccessGrid::Client.new(account_id, secret_key)
# Complete HID org registration with credentials from HID email
result = client.console.hid.orgs.activate(
email: '[email protected]',
password: 'hid-password-123'
)
puts "Completed registration for org: #{result.name}"
puts "Status: #{result.status}"
import AccessGrid from 'accessgrid';
const accountId = process.env.ACCOUNT_ID;
const secretKey = process.env.SECRET_KEY;
const client = new AccessGrid(accountId, secretKey);
const completeRegistration = async () => {
try {
// Complete HID org registration with credentials from HID email
const result = await client.console.hid.orgs.activate({
email: '[email protected]',
password: 'hid-password-123'
});
console.log(`Completed registration for org: ${result.name}`);
console.log(`Status: ${result.status}`);
} catch (error) {
console.error('Error completing HID org registration:', error);
}
};
completeRegistration();
from accessgrid import AccessGrid
import os
account_id = os.getenv('ACCOUNT_ID')
secret_key = os.getenv('SECRET_KEY')
client = AccessGrid(account_id, secret_key)
# Complete HID org registration with credentials from HID email
result = client.console.hid.orgs.activate(
email='[email protected]',
password='hid-password-123'
)
print(f"Completed registration for org: {result.name}")
print(f"Status: {result.status}")
package main
import (
"fmt"
"os"
"github.com/accessgrid/accessgrid-go"
)
func main() {
accountID := os.Getenv("ACCOUNT_ID")
secretKey := os.Getenv("SECRET_KEY")
client, err := accessgrid.NewClient(accountID, secretKey)
if err != nil {
fmt.Printf("Error creating client: %v\n", err)
return
}
// Complete HID org registration with credentials from HID email
result, err := client.Console.HID.Orgs.Activate(&accessgrid.CompleteHIDOrgParams{
Email: "[email protected]",
Password: "hid-password-123",
})
if err != nil {
fmt.Printf("Error completing registration: %v\n", err)
return
}
fmt.Printf("Completed registration for org: %s\n", result.Name)
fmt.Printf("Status: %s\n", result.Status)
}
using AccessGrid;
using System;
using System.Threading.Tasks;
public async Task CompleteRegistrationAsync()
{
var accountId = Environment.GetEnvironmentVariable("ACCOUNT_ID");
var secretKey = Environment.GetEnvironmentVariable("SECRET_KEY");
var client = new AccessGridClient(accountId, secretKey);
// Complete HID org registration with credentials from HID email
var result = await client.Console.HID.Orgs.ActivateAsync(new CompleteHIDOrgRequest
{
Email = "[email protected]",
Password = "hid-password-123"
});
Console.WriteLine($"Completed registration for org: {result.Name}");
Console.WriteLine($"Status: {result.Status}");
}
public class CompleteHIDOrgRequest
{
public string Email { get; set; }
public string Password { get; set; }
}
import com.organization.accessgrid.AccessGridClient;
import com.organization.accessgrid.model.HIDOrg;
import com.organization.accessgrid.model.CompleteHIDOrgParams;
public class HIDOrgService {
private final AccessGridClient client;
public HIDOrgService() {
String accountId = System.getenv("ACCOUNT_ID");
String secretKey = System.getenv("SECRET_KEY");
this.client = new AccessGridClient(accountId, secretKey);
}
public void completeRegistration() throws AccessGridException {
// Complete HID org registration with credentials from HID email
CompleteHIDOrgParams params = CompleteHIDOrgParams.builder()
.email("[email protected]")
.password("hid-password-123")
.build();
HIDOrg result = client.console().hid().orgs().activate(params);
System.out.printf("Completed registration for org: %s%n", result.getName());
System.out.printf("Status: %s%n", result.getStatus());
}
}
<?php
require_once 'vendor/autoload.php';
use AccessGrid\Client;
$accountId = getenv('ACCOUNT_ID');
$secretKey = getenv('SECRET_KEY');
$client = new Client($accountId, $secretKey);
// Complete HID org registration with credentials from HID email
$result = $client->console->hid->orgs->activate([
'email' => '[email protected]',
'password' => 'hid-password-123'
]);
echo "Completed registration for org: {$result->name}\n";
echo "Status: {$result->status}\n";
?>
Response
Empty