AccessGrid.Console (AccessGrid v0.1.0)

Copy Markdown View Source

Manages enterprise template and logging operations.

This module provides functions for card template management (create, update, read), retrieving activity logs, and listing template pairs. These are enterprise-only features requiring special account permissions.

Examples

# Create a new template
{:ok, result} = AccessGrid.Console.create_template(%{
  name: "Employee Badge",
  platform: "apple",
  use_case: "employee_badge",
  protocol: "desfire"
})

# Read full template details
{:ok, template} = AccessGrid.Console.read_template(result.id)

# Get activity logs
{:ok, logs, pagination} = AccessGrid.Console.get_logs(template.id)

Summary

Functions

Completes registration for an HID Origo organization (activate).

Creates a card template pair from an existing Apple and Google template.

Creates a new credential profile.

Registers a new HID Origo organization for the account.

Creates a new landing page.

Creates a new card template.

Creates a new webhook subscription.

Deletes a webhook subscription.

Retrieves activity logs for a card template.

Runs Apple Wallet In-App Provisioning preflight for an access pass.

Lists all pass template pairs for the account.

Lists all credential profiles for the account.

Lists HID Origo organizations registered to the account.

Lists all landing pages for the account.

Lists ledger items for the account, paginated and optionally date-filtered.

Lists webhook subscriptions for the account.

Publishes a card template, moving it out of draft toward ready or in-review.

Retrieves a card template or card template pair by id.

Reveals Smart Tap credentials for a card template, encrypted with the caller's ephemeral public key.

Updates an existing card template.

Types

credential_profile_result()

@type credential_profile_result() ::
  {:ok, AccessGrid.CredentialProfile.t()}
  | {:error, AccessGrid.Types.api_error_reason(),
     AccessGrid.HttpFailure.t() | [atom(), ...]}

credential_profiles_result()

@type credential_profiles_result() ::
  {:ok, [AccessGrid.CredentialProfile.t()]}
  | {:error, AccessGrid.Types.api_error_reason(),
     AccessGrid.HttpFailure.t() | [atom(), ...]}

hid_org_result()

@type hid_org_result() ::
  {:ok, AccessGrid.HidOrg.t()}
  | {:error, AccessGrid.Types.api_error_reason(),
     AccessGrid.HttpFailure.t() | [atom(), ...]}

hid_orgs_result()

@type hid_orgs_result() ::
  {:ok, [AccessGrid.HidOrg.t()]}
  | {:error, AccessGrid.Types.api_error_reason(),
     AccessGrid.HttpFailure.t() | [atom(), ...]}

ios_preflight_result()

@type ios_preflight_result() ::
  {:ok, AccessGrid.IosPreflight.t()}
  | {:error, AccessGrid.Types.api_error_reason(),
     AccessGrid.HttpFailure.t() | [atom(), ...]}

landing_page_result()

@type landing_page_result() ::
  {:ok, AccessGrid.LandingPage.t()}
  | {:error, AccessGrid.Types.api_error_reason(),
     AccessGrid.HttpFailure.t() | [atom(), ...]}

landing_pages_result()

@type landing_pages_result() ::
  {:ok, [AccessGrid.LandingPage.t()]}
  | {:error, AccessGrid.Types.api_error_reason(),
     AccessGrid.HttpFailure.t() | [atom(), ...]}

ledger_items_result()

@type ledger_items_result() ::
  {:ok, [AccessGrid.LedgerItem.t()], map()}
  | {:error, AccessGrid.Types.api_error_reason(),
     AccessGrid.HttpFailure.t() | [atom(), ...]}

logs_result()

@type logs_result() ::
  {:ok, [AccessGrid.Event.t()], map()}
  | {:error, AccessGrid.Types.api_error_reason(),
     AccessGrid.HttpFailure.t() | [atom(), ...]}

pair_summary_result()

@type pair_summary_result() ::
  {:ok, AccessGrid.CardTemplatePair.Summary.t()}
  | {:error, AccessGrid.Types.api_error_reason(),
     AccessGrid.HttpFailure.t() | [atom(), ...]}

pairs_result()

@type pairs_result() ::
  {:ok, [AccessGrid.CardTemplatePair.Summary.t()], map()}
  | {:error, AccessGrid.Types.api_error_reason(),
     AccessGrid.HttpFailure.t() | [atom(), ...]}

publish_result()

@type publish_result() ::
  {:ok, AccessGrid.CardTemplate.PublishResult.t()}
  | {:error, AccessGrid.Types.api_error_reason(),
     AccessGrid.HttpFailure.t() | [atom(), ...]}

result()

smart_tap_reveal_result()

@type smart_tap_reveal_result() ::
  {:ok, AccessGrid.SmartTapReveal.t()}
  | {:error, AccessGrid.Types.api_error_reason(),
     AccessGrid.HttpFailure.t() | [atom(), ...]}

template_result()

webhook_delete_result()

@type webhook_delete_result() ::
  :ok
  | {:error, AccessGrid.Types.api_error_reason(),
     AccessGrid.HttpFailure.t() | [atom(), ...]}

webhook_result()

@type webhook_result() ::
  {:ok, AccessGrid.Webhook.t()}
  | {:error, AccessGrid.Types.api_error_reason(),
     AccessGrid.HttpFailure.t() | [atom(), ...]}

webhooks_result()

@type webhooks_result() ::
  {:ok, [AccessGrid.Webhook.t()], map()}
  | {:error, AccessGrid.Types.api_error_reason(),
     AccessGrid.HttpFailure.t() | [atom(), ...]}

Functions

activate_hid_org(params, opts \\ [])

@spec activate_hid_org(
  map(),
  keyword()
) :: hid_org_result()

Completes registration for an HID Origo organization (activate).

Rails may return extra fields on the response (already_completed: true when the org is already activated, job_queued: true when a registration job is in flight). Those flags are not surfaced on the returned struct — inspect org.status to determine activation state.

Parameters

  • params - Map with:

    • :email - Email used to register the org
    • :password - HID portal password
  • opts - Options:

    • :client - Client struct (optional, defaults to config)

Returns

  • {:ok, %HidOrg{}} - 200 OK (fresh, already-complete, or no-op)
  • {:error, reason, %HttpFailure{}} - 404 if no org matches the email

create_card_template_pair(params, opts \\ [])

@spec create_card_template_pair(
  map(),
  keyword()
) :: pair_summary_result()

Creates a card template pair from an existing Apple and Google template.

The Rails API enforces several validations before the pair is created:

  • Both referenced templates must belong to the current account (404 otherwise).
  • Apple template must have platform == "apple" and Google template platform == "android" (422).
  • Protocol combination must be either both SEOS, or Apple DESFire + Google Smart Tap (422).
  • Both templates must be in status == "ready" (i.e. published) (422).

Parameters

  • params - Map with:

    • :name - Name for the new pair (required)
    • :apple_card_template_id - ex_id of the published Apple template
    • :google_card_template_id - ex_id of the published Google template
  • opts - Options:

    • :client - Client struct (optional, defaults to config)

Returns

  • {:ok, %CardTemplatePair.Summary{}} - Pair created. Same shape as items returned by list_card_template_pairs/1.
  • {:error, reason, %HttpFailure{}} - Creation failed.

create_credential_profile(params, opts \\ [])

@spec create_credential_profile(
  map(),
  keyword()
) :: credential_profile_result()

Creates a new credential profile.

Parameters

  • params - Map with:

    • :name - Display name (required)
    • :app_name - Reader app name (optional, defaults to "KEY-ID-main")
    • :keys - List of %{value, keys_diversified?, source_key_index?} maps; length must match the app's required key count
    • :file_id - Hex file id string (optional, defaults to "00")
  • opts - Options:

    • :client - Client struct (optional, defaults to config)

Returns

  • {:ok, %CredentialProfile{}} - Created
  • {:error, reason, %HttpFailure{}} - 422 on invalid app_name, wrong key count, or validation failure

create_hid_org(params, opts \\ [])

@spec create_hid_org(
  map(),
  keyword()
) :: hid_org_result()

Registers a new HID Origo organization for the account.

Idempotent on nameslug: if an org with the derived slug already exists, Rails returns the existing record with status 200 instead of creating a new one.

Parameters

  • params - Map with:

    • :name - Display name (required)
    • :full_address - Full mailing address
    • :phone - Contact phone number
    • :first_name - Primary contact first name
    • :last_name - Primary contact last name
  • opts - Options:

    • :client - Client struct (optional, defaults to config)

Returns

  • {:ok, %HidOrg{}} - Created (201) or existing (200)
  • {:error, reason, %HttpFailure{}} - 422 on validation failure

create_landing_page(params, opts \\ [])

@spec create_landing_page(
  map(),
  keyword()
) :: landing_page_result()

Creates a new landing page.

Parameters

  • params - Map with:

    • :name - Display name (required)
    • :kind - Landing page kind (required; immutable after creation)
    • :additional_text, :bg_color, :allow_immediate_download, :password, :is_2fa_enabled - Optional fields
    • :logo - Base64-encoded PNG or JPEG image (optional)
  • opts - Options:

    • :client - Client struct (optional, defaults to config)

Returns

  • {:ok, %LandingPage{}} - Created
  • {:error, reason, %HttpFailure{}} - Creation failed

create_template(params, opts \\ [])

@spec create_template(
  map(),
  keyword()
) :: result()

Creates a new card template.

Params are passed straight through to Rails — pass top-level keys using the exact wire names (no nested design: / support_info: wrappers). Image fields (background, logo, icon) accept base64-encoded strings; see AccessGrid.Utils.base64_file/1 for a helper.

Parameters

  • params - Template configuration:

    • :name - Display name for the template (required)
    • :platform - "apple" or "android" (required)
    • :use_case - e.g. "employee_badge" (required)
    • :protocol - "desfire" (Apple), "seos", or "smart_tap" (Android)
    • :allow_on_multiple_devices, :watch_count, :iphone_count - Device limits
    • :background_color, :label_color, :label_secondary_color - Style settings
    • :background, :logo, :icon - Base64-encoded PNG/JPEG images (max 10MB decoded)
    • :support_url, :support_phone_number, :support_email - Support contact info
    • :privacy_policy_url, :terms_and_conditions_url - Legal URLs
    • :credential_profiles - List of credential-profile ex_id strings to attach
    • :landing_pages - List of landing-page ex_id strings to attach
    • :metadata - Custom metadata map
  • opts - Options:

    • :client - Client struct (optional, defaults to config)

Returns

  • {:ok, %CardTemplate.Result{}} - Template created successfully
  • {:error, reason, %HttpFailure{}} - Creation failed

create_webhook(params, opts \\ [])

@spec create_webhook(
  map(),
  keyword()
) :: webhook_result()

Creates a new webhook subscription.

Parameters

  • params - Map with:

    • :name - Display name
    • :url - HTTPS endpoint to receive events
    • :subscribed_events - List of event names (e.g. ["ag.access_pass.issued"])
    • :auth_method - "bearer_token" (default) or "mtls"
  • opts - Options:

    • :client - Client struct (optional, defaults to config)

Returns

  • {:ok, %Webhook{}} - Created. For bearer_token, the struct includes private_key (sensitive — store on receipt, Rails does not return it again). For mtls, the struct includes client_cert and cert_expires_at.
  • {:error, reason, %HttpFailure{}} - 422 on empty or invalid subscribed_events.

delete_webhook(webhook_id, opts \\ [])

@spec delete_webhook(
  String.t(),
  keyword()
) :: webhook_delete_result()

Deletes a webhook subscription.

Parameters

  • webhook_id - The webhook ID to delete
  • opts - Options:
    • :client - Client struct (optional, defaults to config)

Returns

  • :ok - Deleted (Rails returns 204 No Content; there is no body)
  • {:error, reason, %HttpFailure{}} - 404 if id missing

get_logs(template_id, opts \\ [])

@spec get_logs(
  String.t(),
  keyword()
) :: logs_result()

Retrieves activity logs for a card template.

Parameters

  • template_id - The template ID to get logs for
  • opts - Options:
    • :client - Client struct (optional, defaults to config)
    • :page - Page number (default: 1)
    • :per_page - Results per page (default: 50, max: 100)
    • :filters - Map with optional filters:
      • :device - "mobile" or "watch"
      • :start_date - ISO8601 timestamp
      • :end_date - ISO8601 timestamp
      • :event_type - Event type string

Returns

  • {:ok, [%Event{}], pagination} - List of events and pagination info
  • {:error, reason, %HttpFailure{}} - Retrieval failed

ios_preflight(template_id, params, opts \\ [])

@spec ios_preflight(String.t(), map(), keyword()) :: ios_preflight_result()

Runs Apple Wallet In-App Provisioning preflight for an access pass.

Returns the identifiers needed to drive the iOS provisioning flow. Note that Rails returns these keys in camelCase (Apple convention); the resulting struct uses snake_case Elixir-idiomatic field names.

Parameters

  • template_id - The card template ID containing the access pass
  • params - Map with:
    • :access_pass_ex_id - ex_id of the access pass to preflight (required)
  • opts - Options:
    • :client - Client struct (optional, defaults to config)

Returns

  • {:ok, %IosPreflight{}} - Preflight identifiers
  • {:error, reason, %HttpFailure{}} - Preflight failed (404 if template or access pass missing)

list_card_template_pairs(opts \\ [])

@spec list_card_template_pairs(keyword()) :: pairs_result()

Lists all pass template pairs for the account.

Template pairs combine an iOS and Android template for cross-platform pass issuance.

Parameters

  • opts - Options:
    • :client - Client struct (optional, defaults to config)
    • :page - Page number (default: 1)
    • :per_page - Results per page (default: 50, max: 100)

Returns

  • {:ok, [%CardTemplatePair.Summary{}], pagination} - List of pairs and pagination info
  • {:error, reason, %HttpFailure{}} - Retrieval failed

list_credential_profiles(opts \\ [])

@spec list_credential_profiles(keyword()) :: credential_profiles_result()

Lists all credential profiles for the account.

Rails returns a flat JSON array — no wrapper, no pagination — so the result is {:ok, list} rather than {:ok, list, pagination}.

Parameters

  • opts - Options:
    • :client - Client struct (optional, defaults to config)

Returns

  • {:ok, [%CredentialProfile{}]} - List of credential profiles (may be empty)
  • {:error, reason, %HttpFailure{}} - Retrieval failed

list_hid_orgs(opts \\ [])

@spec list_hid_orgs(keyword()) :: hid_orgs_result()

Lists HID Origo organizations registered to the account.

Rails returns a flat JSON array — no wrapper, no pagination.

Parameters

  • opts - Options:
    • :client - Client struct (optional, defaults to config)

Returns

  • {:ok, [%HidOrg{}]} - List of HID orgs (may be empty)
  • {:error, reason, %HttpFailure{}} - Retrieval failed

list_landing_pages(opts \\ [])

@spec list_landing_pages(keyword()) :: landing_pages_result()

Lists all landing pages for the account.

Rails returns a flat JSON array — there is no landing_pages wrapper and no pagination, so the result is {:ok, list} rather than {:ok, list, pagination}.

Parameters

  • opts - Options:
    • :client - Client struct (optional, defaults to config)

Returns

  • {:ok, [%LandingPage{}]} - List of landing pages (may be empty)
  • {:error, reason, %HttpFailure{}} - Retrieval failed

list_ledger_items(opts \\ [])

@spec list_ledger_items(keyword()) :: ledger_items_result()

Lists ledger items for the account, paginated and optionally date-filtered.

Parameters

  • opts - Options:
    • :client - Client struct (optional, defaults to config)
    • :page - Page number (default: 1)
    • :per_page - Results per page (default: 50, max: 100)
    • :start_date - ISO8601 timestamp; filters items created on/after
    • :end_date - ISO8601 timestamp; filters items created on/before

Returns

  • {:ok, [%LedgerItem{}], pagination} - List + pagination map
  • {:error, reason, %HttpFailure{}} - 422 on bad date format

list_webhooks(opts \\ [])

@spec list_webhooks(keyword()) :: webhooks_result()

Lists webhook subscriptions for the account.

Parameters

  • opts - Options:
    • :client - Client struct (optional, defaults to config)
    • :page - Page number (default: 1)
    • :per_page - Results per page (default: 50, max: 100)

Returns

  • {:ok, [%Webhook{}], pagination} - List + pagination map
  • {:error, reason, %HttpFailure{}} - Retrieval failed

publish_template(template_id, opts \\ [])

@spec publish_template(
  String.t(),
  keyword()
) :: publish_result()

Publishes a card template, moving it out of draft toward ready or in-review.

For Android+SEOS templates, Rails also syncs the template to the HID portal as part of publish. If that sync fails, the template is rolled back to draft and this call returns {:error, :validation_failed, failure} with a field-tagged error message in failure.body_decoded["message"].

Parameters

  • template_id - The card template id to publish
  • opts - Options:
    • :client - Client struct (optional, defaults to config)

Returns

  • {:ok, %CardTemplate.PublishResult{}} - 200 OK with {id, status}. status is "publishing" (already in flight), "in-review" (Apple queued), or "ready" (Android, immediate).
  • {:error, reason, %HttpFailure{}} - 404 if template missing, 422 on validation failure or HID-sync failure (for Android+SEOS).

read_template(template_id, opts \\ [])

@spec read_template(
  String.t(),
  keyword()
) :: template_result()

Retrieves a card template or card template pair by id.

The /v1/console/card-templates/:id endpoint serves both shapes: a single template, or a pair containing two member templates. Match on the returned struct to tell them apart.

Parameters

  • template_id - The template (or pair) id to retrieve
  • opts - Options:
    • :client - Client struct (optional, defaults to config)

Returns

  • {:ok, %CardTemplate{}} - Single template
  • {:ok, %CardTemplatePair{}} - Pair, with member templates under :templates
  • {:error, reason, %HttpFailure{}} - Retrieval failed

reveal_smart_tap(template_id, params, opts \\ [])

@spec reveal_smart_tap(String.t(), map(), keyword()) :: smart_tap_reveal_result()

Reveals Smart Tap credentials for a card template, encrypted with the caller's ephemeral public key.

The caller decrypts the returned encrypted_private_key with their corresponding private key. Each request must use a fresh ephemeral keypair — Rails enforces single-use via the pubkey fingerprint (returns 409 if reused).

Parameters

  • template_id - The card template id (must be SmartTap protocol with a smart_tap_key)

  • params - Map with:

    • :client_public_key - PEM-encoded public key string (required)
  • opts - Options:

    • :client - Client struct (optional, defaults to config)

Returns

  • {:ok, %SmartTapReveal{}} - Encrypted credentials envelope
  • {:error, :not_found, %HttpFailure{}} - Template missing, not SmartTap, or no smart_tap_key
  • {:error, :conflict, %HttpFailure{}} - This client_public_key has been used before
  • {:error, :validation_failed, %HttpFailure{}} - Invalid PEM or save failure

update_landing_page(landing_page_id, params, opts \\ [])

@spec update_landing_page(String.t(), map(), keyword()) :: landing_page_result()

Updates an existing landing page.

The :kind field is immutable after creation. Sending a different value returns 422.

Parameters

  • landing_page_id - The landing page ID to update
  • params - Same fields as create_landing_page/2 except :kind
  • opts - Options:
    • :client - Client struct (optional, defaults to config)

Returns

  • {:ok, %LandingPage{}} - Updated
  • {:error, reason, %HttpFailure{}} - 404 if id missing, 422 on validation

update_template(template_id, params, opts \\ [])

@spec update_template(String.t(), map(), keyword()) :: result()

Updates an existing card template.

Parameters

  • template_id - The template ID to update
  • params - Fields to update (same options as create_template)
  • opts - Options:
    • :client - Client struct (optional, defaults to config)

Returns

  • {:ok, %CardTemplate.Result{}} - Template updated successfully
  • {:error, reason, %HttpFailure{}} - Update failed