Creating and Encoding Card-based Credentials

Learn how to create a card-based credential and then encode this credential on a plastic card.

Some access control systems require encoding a plastic card credential with the data necessary to enable access. This process involves creating a credential with the required access permissions and then using a card encoder to write the credential to the card.

This process consists of the following basic steps:

  1. Set up an ACS user and create a credential with the access_method set to card. See the system integration guide for your ACS provider to learn specific requirements, such as configuring entrances and access schedules. See Set Up an ACS User and Card Credential.

  2. Use the /acs/encoders/list endpoint to retrieve a list of available encoders. Then, choose the encoder that you want to use to write the credential to the card. See Retrieve Encoders.

  3. Use the /acs/encoders/encode_credential endpoint to encode the credential on the card, using the encoder that you have chosen. See Encode the Card.

  4. Confirm that the card was encoded successfully using polling or a webhook. See Confirm Successful Encoding. Also, see a list of common encoding errors.

Once you have written a credential to a card, you cannot reuse the credential for another card. That is, you must create a separate credential for each card. However, you can reuse a card by re-encoding the card with a new credential.


1. Set Up an ACS User and Card Credential

This example shows how to create an ACS user and card-based credential. Note that the is_issued property of the resulting credential is false, which means the the credential is ready to be written to a card and has not yet been used to encode a card.

Depending on your specific access control system, creating an ACS user or credential may require additional parameters. For details, see the system integration guide for your ACS.

Code:

# Step 1:
# Create the new ACS user.
acs_user = seam.acs.users.create(
  acs_system_id = "11111111-1111-1111-1111-111111111111",
  full_name = "Jane Doe",
  email_address = "[email protected]"
)

# Step 2:
# Create a card-based credential for each entrance for the ACS user.
credential = seam.acs.credentials.create(
  acs_user_id = acs_user.acs_user_id,
  access_method = "card",
  # List the IDs of the entrances to which
  # you want to grant access.
  allowed_acs_entrance_ids = [
    room_101.seam_acs_entrance_id
  ],
  starts_at = "2024-12-01T15:00:00.000Z",
  ends_at = "2024-12-04T12:00:00.000Z"
)

Output:

AcsCredential(
  acs_credential_id='66666666-6666-6666-6666-666666666666',
  acs_user_id='33333333-3333-3333-3333-333333333333',
  access_method='card',
  starts_at='2024-12-01T15:00:00.000Z',
  ends_at='2024-12-04T12:00:00.000Z',
  is_issued=False
  ...
)

2. Retrieve Encoders

There may be multiple encoders at a location, so itโ€™s important to select the right one to encode the credential.

This example shows how to retrieve all encoders in a building connected to a single ACS system. Once you've identified the encoder you'd like to use, grab the acs_encoder_id of the chosen encoder for the next step.

Code:

seam.acs.encoders.list(
  acs_system_ids = [building_system_id]
)

Output:

[
  AcsEncoder(
    acs_encoder_id='33333333-4444-5555-6666-777777777777',
    display_name='Front Desk',
    ...
  )
  ...
]

3. Encode the Card

Use /acs/encoders/encode_credential to start the card writing procedure that stores the credential data on the plastic key card.

Code:

encoding_action_attempt = seam.acs.encoders.encode_credential(
  acs_credential_id = credential.acs_credential_id,
  acs_encoder_id = encoder.acs_encoder_id
)

Output:

ActionAttempt(
  status='pending',
  action_attempt_id='11111111-2222-3333-4444-555555555555',
  action_type='ENCODE_CREDENTIAL',
  result=null,
  error=null
)

4. Confirm Successful Encoding

Once you issue a request to encode the credential onto the card, it is important to confirm that the encoding process completes successfully. You can use polling or a webhook.

Confirm Successful Encoding by Polling

When you make an /acs/encoders/encode_credential request, Seam returns an action attempt. To confirm that the card encoding was successful, you can poll this action attempt, until its status becomes success.

Code:

seam.action_attempts.get(
  action_attempt_id = encoding_action_attempt.action_attempt_id
)

Output:

ActionAttempt(
  status='success',
  action_attempt_id='11111111-2222-3333-4444-555555555555',
  action_type='ENCODE_CREDENTIAL',
  result={
    acs_credential_id='66666666-6666-6666-6666-666666666666',
    card_number='1234abc',
    is_issued=True,
    issued_at='2024-10-23T19:46:06.113Z',
    ...
  },
  error=null
)

View Credential Properties

It is also useful to note that Seam assigns values to various card-related properties on the credential when the encoder has finished encoding the card. For example, acs_credential.is_issued becomes true, and acs_credential.card_number and acs_credential.issued_at receive values. You can retrieve the credential to view these properties.

Code:

seam.acs.credentials.get(
  acs_credential_id = credential.acs_credential_id
)

Output:

AcsCredential(
  acs_credential_id='66666666-6666-6666-6666-666666666666',
  acs_user_id='33333333-3333-3333-3333-333333333333',
  access_method='card',
  starts_at='2024-12-01T15:00:00.000Z',
  ends_at='2024-12-04T12:00:00.000Z',
  is_issued=True,
  card_number='1234abc',
  issued_at='2024-10-23T19:46:06.113Z',
  ...
)

Confirm Successful Encoding by Using a Webhook

To confirm successful encoding, you can use a webhook to listen for an acs_credential.issued event that contains the acs_credential_id in the payload.

{
    "event_id": "22222222-3333-4444-5555-666666666666",
    "event_description": "An ACS credential was issued.",
    "event_type": "acs_credential.issued",
    "workspace_id": "00000000-0000-0000-0000-000000000000",
    "created_at": "2024-10-23T19:47:35.375Z",
    "occurred_at": "2024-10-23T19:47:35.356Z",
    "acs_system_id": "11111111-1111-1111-1111-111111111111",
    "acs_credential_id": "66666666-6666-6666-6666-666666666666",
    "connected_account_id": "11111111-1111-1111-1111-222222222222"
}

Common Encoding Errors

Error
Description

no_card_on_encoder

No card was placed on the encoder.

incompatible_card_format

A card with an incompatible card format was placed on the encoder.

uncategorized_error

Any other encoding error.

Last updated

Was this helpful?

Revision created

ci: Generate docs