Catalog PyPI
PACKAGE EXPLORERView in registry

accessgrid

PyPI

Python SDK for the AccessGrid API

Versions collected1
Direct dependencies11From release 0.6.0
Last observed20 Oct, 17:57 UTC

README

Version 0.6.0 documentation

AccessGrid SDK

A Python SDK for interacting with the AccessGrid.com API. This SDK provides a simple interface for managing NFC key cards and enterprise templates. Full docs at https://www.accessgrid.com/docs

Installation

pip install accessgrid

Quick Start

from accessgrid import AccessGrid

account_id = os.environ.get('ACCOUNT_ID')
secret_key = os.environ.get('SECRET_KEY')

client = AccessGrid(account_id, secret_key)

API Reference

Access Cards

Provision a new card

card = client.access_cards.provision(
    card_template_id="0xd3adb00b5",
    employee_id="123456789",
    card_number="123456",
    site_code="100",
    full_name="Employee name",
    email="employee@yourwebsite.com",
    phone_number="+19547212241",
    classification="full_time",
    department="Engineering",
    location="San Francisco",
    site_name="HQ Building A",
    workstation="4F-207",
    mail_stop="MS-401",
    company_address="123 Main St, San Francisco, CA 94105",
    start_date="2025-01-31T22:46:25.601Z",
    expiration_date="2025-04-30T22:46:25.601Z",
    employee_photo="[image_in_base64_encoded_format]",
    title="Engineering Manager",
    metadata={
        "department": "engineering",
        "badge_type": "contractor"
    }
)

Update a card

card = client.access_cards.update(
    card_id="0xc4rd1d",
    employee_id="987654321",
    full_name="Updated Employee Name",
    classification="contractor",
    department="Marketing",
    location="New York",
    site_name="NYC Office",
    workstation="2F-105",
    mail_stop="MS-200",
    company_address="456 Broadway, New York, NY 10013",
    expiration_date="2025-02-22T21:04:03.664Z",
    employee_photo="[image_in_base64_encoded_format]",
    title="Senior Developer"
)

List NFC keys / Access passes

# List all cards for a template
cards = client.access_cards.list(template_id="0xd3adb00b5")
for card in cards:
    print(card)  # Outputs: AccessCard(name='Employee Name', id='0xc4rd1d', state='active')

# Filter cards by state
active_cards = client.access_cards.list(template_id="0xd3adb00b5", state="active")

Manage card states

# Suspend a card
client.access_cards.suspend(card_id="0xc4rd1d")

# Resume a card
client.access_cards.resume(card_id="0xc4rd1d")

# Unlink a card
client.access_cards.unlink(card_id="0xc4rd1d")

# Delete a card
client.access_cards.delete(card_id="0xc4rd1d")

Enterprise Console

Create a template

template = client.console.create_template(
    name="Employee Access Pass",
    platform="apple",
    use_case="corporate_id",
    protocol="desfire",
    allow_on_multiple_devices=True,
    watch_count=2,
    iphone_count=3,
    background_color="#FFFFFF",
    label_color="#000000",
    label_secondary_color="#333333",
    support_url="https://help.yourcompany.com",
    support_phone_number="+1-555-123-4567",
    support_email="support@yourcompany.com",
    privacy_policy_url="https://yourcompany.com/privacy",
    terms_and_conditions_url="https://yourcompany.com/terms",
    metadata={
        "version": "2.1",
        "approval_status": "approved"
    }
)

Update a template

template = client.console.update_template(
    card_template_id="0xd3adb00b5",
    name="Updated Employee NFC key",
    allow_on_multiple_devices=True,
    watch_count=2,
    iphone_count=3,
    support_url="https://help.yourcompany.com",
    support_phone_number="+1-555-123-4567",
    support_email="support@yourcompany.com",
    privacy_policy_url="https://yourcompany.com/privacy",
    terms_and_conditions_url="https://yourcompany.com/terms"
)

Read a template

template = client.console.read_template(card_template_id="0xd3adb00b5")

Delete a template

client.console.delete_template("0xd3adb00b5")

Publish a template

result = client.console.publish_template(card_template_id="0xd3adb00b5")

print(f"Template {result.id} status: {result.status}")
# status is one of: "publishing" (already in flight), "in-review" (Apple
# queued), or "ready" (Android immediate)

Reveal a SmartTap private key

Fetches the template's SmartTap private key, decrypted client-side. The SDK generates a fresh ephemeral P-256 keypair per call, submits the public half, and decrypts the server's response — you get the plaintext PEM back without touching any crypto.

reveal = client.console.reveal_smart_tap(card_template_id="0xd3adb00b5")

print(f"Key version:  {reveal.key_version}")
print(f"Collector ID: {reveal.collector_id}")
print(f"Fingerprint:  {reveal.fingerprint}")
print(reveal.private_key)  # PEM — store in your reader/collector key vault

The server enforces single-use on pubkey fingerprint and rate-limits to 1 per minute per account. The SDK uses a fresh keypair every call, so single-use is satisfied automatically.

Get event logs

from datetime import datetime, timedelta

events = client.console.event_log(
    card_template_id="0xd3adb00b5",
    filters={
        "device": "mobile",  # "mobile" or "watch"
        "start_date": (datetime.now() - timedelta(days=30)).isoformat(),
        "end_date": datetime.now().isoformat(),
        "event_type": "install"
    }
)

iOS In-App Provisioning Preflight

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}")

List ledger items

from datetime import datetime, timezone, timedelta

start_date = (datetime.now(timezone.utc) - timedelta(days=30)).isoformat()
end_date = datetime.now(timezone.utc).isoformat()

result = client.console.ledger_items(
    page=1,
    per_page=50,
    start_date=start_date,
    end_date=end_date
)

for item in result['ledger_items']:
    print(f"Amount: {item['amount']}, Kind: {item['kind']}, Date: {item['created_at']}")
    if item.get('access_pass'):
        print(f"  Access Pass: {item['access_pass']['ex_id']}")
        if item['access_pass'].get('pass_template'):
            print(f"  Card Template: {item['access_pass']['pass_template']['ex_id']}")

Card Template Pairs

Create a card template pair

Both templates must be published (status: ready) and unpaired. Valid protocol combinations are both SEOS, or Apple DESFire with Google Smart Tap.

pair = client.console.create_pass_template_pair(
    name="Employee Badge Pair",
    apple_card_template_id="0xapplet3mp14t3",
    google_card_template_id="0xgoogl3t3mp14t3"
)

print(f"Created pair: {pair.name} (ID: {pair.id})")

List card template pairs

result = client.console.list_pass_template_pairs(page=1, per_page=50)

for pair in result['card_template_pairs']:
    print(f"{pair.name} (ID: {pair.id})")
    if pair.ios_template:
        print(f"  iOS: {pair.ios_template.id}")
    if pair.android_template:
        print(f"  Android: {pair.android_template.id}")

Landing Pages

List landing pages

landing_pages = client.console.list_landing_pages()

for page in landing_pages:
    print(f"ID: {page.id}, Name: {page.name}, Kind: {page.kind}")
    print(f"  Password Protected: {page.password_protected}")
    if page.logo_url:
        print(f"  Logo URL: {page.logo_url}")

Create a landing page

landing_page = client.console.create_landing_page(
    name="Miami Office Access Pass",
    kind="universal",
    additional_text="Welcome to the Miami Office",
    bg_color="#f1f5f9",
    allow_immediate_download=True
)

print(f"Landing page created: {landing_page.id}")
print(f"Name: {landing_page.name}, Kind: {landing_page.kind}")

Update a landing page

landing_page = client.console.update_landing_page(
    landing_page_id="0xlandingpage1d",
    name="Updated Miami Office Access Pass",
    additional_text="Welcome! Tap below to get your access pass.",
    bg_color="#e2e8f0"
)

print(f"Landing page updated: {landing_page.id}")
print(f"Name: {landing_page.name}")

Credential Profiles

List credential profiles

profiles = client.console.credential_profiles.list()

for profile in profiles:
    print(f"ID: {profile.id}, Name: {profile.name}, AID: {profile.aid}")

Create a credential profile

profile = client.console.credential_profiles.create(
    name='Main Office Profile',
    app_name='KEY-ID-main',
    keys=[
        {'value': 'your_32_char_hex_master_key_here'},
        {'value': 'your_32_char_hex__read_key__here'}
    ]
)

print(f"Profile created: {profile.id}")
print(f"AID: {profile.aid}")

Delete a credential profile

client.console.credential_profiles.delete('cp-1')

Webhooks

Create a webhook

webhook = client.console.webhooks.create(
    name='Production',
    url='https://example.com/webhooks',
    subscribed_events=['ag.access_pass.issued']
)

print(f"Webhook created: {webhook.id}")
print(f"Private key: {webhook.private_key}")

List webhooks

webhooks = client.console.webhooks.list()

for webhook in webhooks:
    print(f"ID: {webhook.id}, Name: {webhook.name}")

Delete a webhook

client.console.webhooks.delete('abc123')

Verify a webhook

result = client.console.webhooks.verify('abc123')

print(f"Webhook {result.id} verified: {result.verified}")
# verified is True when already verified, or False when a verification
# handshake has just been initiated

HID Organizations

Create a HID organization

org = client.console.hid.orgs.create(
    name='My Organization',
    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}")

Complete HID org registration

After creating an organization, complete the registration with credentials from your HID email:

result = client.console.hid.orgs.activate(
    email='admin@example.com',
    password='hid-password-123'
)

print(f"Completed registration for org: {result.name}")
print(f"Status: {result.status}")

List all HID organizations

orgs = client.console.hid.orgs.list()

for org in orgs:
    print(f"Org ID: {org.id}, Name: {org.name}, Slug: {org.slug}")

Configuration

The SDK can be configured with custom options:

client = AccessGrid(
    account_id,
    secret_key
)

Error Handling

The SDK throws errors for various scenarios including:

  • Missing required credentials
  • API request failures
  • Invalid parameters
  • Server errors

Example error handling:

try:
    card = client.access_cards.provision(
        # ... parameters
    )
except AccessGridError as error:
    print(f'Failed to provision card: {str(error)}')

Requirements

  • Python 3.7 or higher
  • Required packages:
    • requests
    • cryptography
    • python-dateutil

Security

The SDK automatically handles:

  • Request signing using HMAC-SHA256
  • Secure payload encoding
  • Authentication headers
  • HTTPS communication

Never expose your secret_key in source code. Always use environment variables or a secure configuration management system.

License

MIT License - See LICENSE file for details.

Feature Matrix

EndpointMethodSupported
POST /v1/key-cardsaccess_cards.issue()Y
GET /v1/key-cards/{id}access_cards.get()Y
PATCH /v1/key-cards/{id}access_cards.update()Y
GET /v1/key-cardsaccess_cards.list()Y
POST /v1/key-cards/{id}/suspendaccess_cards.suspend()Y
POST /v1/key-cards/{id}/resumeaccess_cards.resume()Y
POST /v1/key-cards/{id}/unlinkaccess_cards.unlink()Y
POST /v1/key-cards/{id}/deleteaccess_cards.delete()Y
POST /v1/console/card-templatesconsole.create_template()Y
PUT /v1/console/card-templates/{id}console.update_template()Y
GET /v1/console/card-templates/{id}console.read_template()Y
DELETE /v1/console/card-templates/{id}console.delete_template()Y
POST /v1/console/card-templates/{id}/publishconsole.publish_template()Y
POST /v1/console/card-templates/{id}/smart-tap/revealconsole.reveal_smart_tap()Y
GET /v1/console/card-templates/{id}/logsconsole.get_logs() / console.event_log()Y
GET /v1/console/card-template-pairsconsole.list_pass_template_pairs()Y
POST /v1/console/card-template-pairsconsole.create_pass_template_pair()Y
POST /v1/console/card-templates/{id}/ios_preflightconsole.ios_preflight()Y
GET /v1/console/ledger-itemsconsole.ledger_items()Y
GET /v1/console/landing-pagesconsole.list_landing_pages()Y
POST /v1/console/landing-pagesconsole.create_landing_page()Y
PUT /v1/console/landing-pages/{id}console.update_landing_page()Y
GET /v1/console/credential-profilesconsole.credential_profiles.list()Y
POST /v1/console/credential-profilesconsole.credential_profiles.create()Y
DELETE /v1/console/credential-profiles/{id}console.credential_profiles.delete()Y
GET /v1/console/webhooksconsole.webhooks.list()Y
POST /v1/console/webhooksconsole.webhooks.create()Y
DELETE /v1/console/webhooks/{id}console.webhooks.delete()Y
POST /v1/console/webhooks/{id}/verifyconsole.webhooks.verify()Y
POST /v1/console/hid/orgsconsole.hid.orgs.create()Y
POST /v1/console/hid/orgs/activateconsole.hid.orgs.activate()Y
GET /v1/console/hid/orgsconsole.hid.orgs.list()Y

Downloads & popularity

Awaiting observations

No metric observations yet

Download counts and popularity will appear here as the collector receives them.

Versions 1

Collected releases
VersionPublishedDirect dependenciesOpen version
0.6.04 Aug 202611

Package advisories

0
No matching advisories collected

This describes our collected data; it is not a security assessment.

Repository

PENDING
access-grid/accessgrid-py

Shared repository data · GitHub

License detected in repository
Not collected

Metadata history

Meaningful changes
Current collected state Current

Observed since 20 Oct, 17:57 UTC

No superseded metadata states collected. Unchanged observations do not create new revisions.

Record identity

package:7244abc3e0be71aec19775fe73c69fd04af130fcbac44c32202ae5394503b4d4