---
title: Getting Started
slug: frameworks
createdAt: 2026-05-26T05:24:56.000Z
---

# Introduction

## Purpose of This Document

This manual describes how to build a third-party integration with Sine's **Access Control Integration (ACI)** specification. It is the primary technical reference for developers implementing an ACI-compatible endpoint that connects an external access control system (ACS) to the Sine platform.

The document covers the ACI architecture, the full credential lifecycle, the endpoint contracts your integration must fulfil, and how to test that everything works correctly before going live.

## Who This Document Is For

This document is written for **developers** building or maintaining an integration between a third-party ACS and Sine using the ACI specification. You should be comfortable with:

- Building and hosting REST API endpoints
- Handling JSON request and response bodies
- Basic authentication patterns (bearer tokens, shared secrets, or similar)
- The general concepts behind access control systems (credentials, card holders, access groups)

No prior knowledge of Sine's internal architecture is assumed. Sine-specific concepts are introduced and explained where they first appear.

## What ACI Enables

Sine's Access Control Integration specification provides a standardised interface through which Sine can manage visitor and contractor credentials across a wide range of physical access control systems.

When an integration is built to the ACI specification, Sine is able to:

- Automatically **provision** an access credential in your ACS when a visitor or contractor record is created in Sine
- **Activate** that credential when the person is approved to access the site
- **Deprovision** the credential when their visit ends or their access is revoked

Your integration acts as the bridge between Sine's credential lifecycle events and the specific API or SDK of your ACS.

## Scope and Limitations

This document covers the ACI integration contract - the inputs Sine will send to your endpoint and the outputs Sine expects in return. It does **not** cover:

- How Sine is configured on the site administrator's side (outside the scope of this document)
- ACS-specific implementation details (your team's responsibility)
- Non-credential ACS operations such as door unlock commands or alarm management

ACI is designed specifically for **credential lifecycle management**. If your integration needs to support additional ACS operations outside that scope, those are outside the ACI specification and would require a separate integration approach.

## Prerequisites

Before you begin implementation, ensure you have the following in place:

- Access to a Sine test environment (provided by your Sine contact during onboarding)
- API credentials for authenticating your endpoint to Sine (provided during integration registration - see [Testing & Deployment](<./Testing _ Deployment.mdx>))
- A publicly accessible HTTPS endpoint (or a tunnelling tool such as ngrok for local development)
- Access to your ACS vendor's API or SDK documentation

# Architecture Overview

## System Context

ACI sits between the Sine platform and your physical access control system. There are three distinct layers in a typical deployment:

| Layer                    | Owner                 | Responsibility                                       |
| ------------------------ | --------------------- | ---------------------------------------------------- |
| **Sine Platform**        | Sine                  | Visitor lifecycle, policy checks, credential display |
| **Integration Endpoint** | You (the developer)   | Translates Sine requests into ACS operations         |
| **Physical ACS**         | ACS vendor / customer | Enforces access at readers, turnstiles, or doors     |

Sine never communicates directly with your ACS. All requests flow through the integration endpoint you build and host. This is the only surface you need to implement to be ACI-compatible.

```mermaid
flowchart LR
    sine["Sine Platform\n(Cloud)"]
    integration["Your Integration Endpoint\n(HTTPS API)"]
    acs["Physical ACS\n(Readers / Turnstiles)"]
    visitor(["Visitor"])

    sine -->|"POST Provision\nPOST Activate\nPOST Deprovision"| integration
    integration -->|"Create / enable /\nrevoke credential"| acs
    acs -.->|"checkoutUrl callback\n(optional)"| sine
    visitor -->|"Presents credential\n(QR or physical card)"| acs
```

Dashed lines indicate the optional ACS-initiated checkout callback, described in [Check-Out Flow - ACS Initiated](./#check-out-flow---acs-initiated-optional) below.

## Credential Types

ACI supports two credential types, controlled by the `credentialType` field sent in each request. The type determines which end holds the credential identifier at the start of the Provision call - and this has meaningful implications for how your integration should behave.

| Credential Type       | Value      | Who holds the identifier?                                   | What the visitor uses                 |
| --------------------- | ---------- | ----------------------------------------------------------- | ------------------------------------- |
| **Digital (QR code)** | `digital`  | ACS generates it and returns it in the Provision response   | QR code displayed or printed by Sine  |
| **Physical card**     | `physical` | Sine holds it - pre-assigned to the visitor before check-in | A physical card handed to the visitor |

A third type, `virtual`, may appear in some configurations and follows the same flow as `digital` unless your ACS handles it differently.

The credential type is sent on every lifecycle request, so your integration always knows which mode is in effect.

## Check-In Flow - Digital Credential (QR Code)

For digital credentials, the ACS is responsible for generating a unique, unpredictable credential identifier (the `barcode`). Sine does not know the credential value until the Provision response is received.

```mermaid
sequenceDiagram
    autonumber
    participant V as Visitor
    participant S as Sine Platform
    participant I as Integration Endpoint
    participant A as Physical ACS

    V->>S: Check in (kiosk / app / dashboard)
    S->>I: POST /provision
    note right of S: credentialType: "digital"<br/>visit, visitor, host, validity window, access groups
    I->>A: Create credential in pending/inactive state
    A-->>I: New credential identifier (barcode)
    I-->>S: 201 PROVISIONED + barcode + ACS correlation IDs
    S->>V: Display or print QR code credential
    S->>I: POST /activate
    note right of S: barcode + ACS correlation IDs
    I->>A: Enable credential for access
    A-->>I: Credential active
    I-->>S: 200 ACTIVATED
    V->>A: Present QR code at reader
    A-->>V: Access granted
```

**Key points:**

- Provision is **synchronous and blocking** - Sine waits for the response before displaying the QR code. A slow or failed response will delay or block check-in.
- Activate is **asynchronous and non-blocking** - Sine fires the request and considers the visitor checked in regardless of the outcome. A failed Activate is logged, but does not roll back check-in.
- The `barcode` must be **unpredictable** (non-sequential, non-guessable). Do not return card numbers, visitor IDs, or any value that could be enumerated.
- The `barcode` returned by Provision becomes the `badgeNumber` Sine sends in all subsequent Activate and Deprovision calls.

## Check-In Flow - Physical Card Credential

For physical credentials, the card identifier is pre-assigned to the visitor in Sine before check-in begins - typically by a receptionist selecting a card from the site's card pool. Sine sends this identifier in the Provision request body as `badgeNumber`.

In the most common configuration - where Sine's Asset Management controls the card pool - **your integration should create a fresh cardholder and credential record for each visit**. Sine manages card assignment centrally, so the card will not typically pre-exist in your ACS.

If your ACS independently manages a pre-loaded card inventory (cards pre-programmed into the ACS outside of Sine), you may need to match an existing record instead:

- **Create fresh (standard):** Create a new cardholder and link it to the card number. This is the expected behaviour for integrations using Sine's Asset Management.
- **Match existing (for ACS-managed card pools):** Look for a pre-existing card record in the ACS and attach the visitor's cardholder to it. Use this only when the ACS maintains its own independent card inventory.

Document your chosen behaviour clearly for site administrators.

```mermaid
sequenceDiagram
    autonumber
    participant R as Receptionist
    participant V as Visitor
    participant S as Sine Platform
    participant I as Integration Endpoint
    participant A as Physical ACS

    R->>S: Assign physical card to visitor in Sine (e.g. Card #1234)
    V->>S: Check in (kiosk / app / dashboard)
    S->>I: POST /provision
    note right of S: credentialType: "physical"<br/>badgeNumber: "1234" (pre-assigned card number)<br/>visit, visitor, host, validity window, access groups
    I->>A: Create cardholder + link to card #1234<br/>(fresh creation is standard)
    A-->>I: Cardholder created
    I-->>S: 201 PROVISIONED + barcode (card number) + ACS correlation IDs
    note right of I: No QR generated — visitor already holds the physical card
    S->>I: POST /activate
    note right of S: badgeNumber + ACS correlation IDs
    I->>A: Enable card access at readers
    A-->>I: Card access enabled
    I-->>S: 200 ACTIVATED
    V->>A: Tap physical card at reader
    A-->>V: Access granted
```

**Key points:**

- Sine sends the card number as `badgeNumber` in the Provision request. Your integration must use this value to identify which card to associate with the visitor cardholder.
- No QR code is generated or displayed after Provision - the visitor already has the physical card.
- The `barcode` you return in the Provision response is typically the same card number Sine sent. Sine stores it and sends it back as `badgeNumber` on Activate and Deprovision.

## Physical Card Inventory and Asset Management

For sites using physical card credentials, Sine's Asset Management feature allows site administrators to pre-register a pool of physical card numbers. When a visitor checks in, the receptionist (or automated assignment logic) assigns an available card to that visitor from the pool.

**The standard flow for Asset Management-managed cards:**

1. Administrator registers card numbers in Sine during site setup.
2. Visitor checks in → Sine assigns a card from the available pool.
3. Sine sends `POST /provision` with the assigned `badgeNumber` → your ACS creates the cardholder and credential fresh.
4. Visitor checks out → Sine sends `POST /deprovision` → your ACS removes the credential and cardholder record.
5. The card number is returned to the pool in Sine, ready for the next visitor.

Because Sine manages the card pool centrally, **the card will not typically pre-exist in your ACS**. Creating a fresh record on each Provision is the expected primary behaviour.

**When might a pre-existing credential be encountered?**

Some sites operate ACS installations where cards are pre-programmed directly into the ACS outside of Sine. In these cases, Provision may receive a `badgeNumber` that already exists in your ACS. If your integration targets this setup, implement a match-existing or upsert strategy and document the behaviour clearly for site administrators.

**What about&#x20;**`deactivateOnly`**?**

For most installations, full deprovision on checkout is the correct behaviour. However, some sites prefer to retain credential records in the ACS after checkout - for audit history, or because their ACS independently manages credential lifecycle. In these configurations, Sine can be set to send `deactivateOnly=true` on Deprovision. See [Check-Out Flow - Sine Initiated](./#check-out-flow---sine-initiated) for the full deprovision modes.

## Check-Out Flow - Sine Initiated

The check-out flow is structurally the same for both credential types. When a visitor checks out in Sine (manually by staff, by the visitor, or by auto-checkout), Sine sends a Deprovision request.

`deactivateOnly` is an optional mode flag, not the default. In the standard case - including all Asset Management flows - full deprovision is the expected behaviour. Sine sends `deactivateOnly=true` only when a site is specifically configured to retain credential records. See the section above for context.

| Credential Type | Deprovision behaviour                                                                        |
| --------------- | -------------------------------------------------------------------------------------------- |
| Digital (QR)    | Usually revoke/remove credential, unless `deactivateOnly=true` is explicitly sent            |
| Physical card   | Usually revoke/deprovision on normal return, unless `deactivateOnly=true` is explicitly sent |

When `deactivateOnly=true`, your integration should deactivate access without destructive deletion of records required for later reuse or investigation.

If you implement a dedicated deactivate-only path, you **must** ensure Provision can handle credential identifiers (`badgeNumber`/`barcode`) that may already exist in the ACS. This is critical for reuse scenarios and for avoiding duplicate-key or uniqueness conflicts.

```mermaid
sequenceDiagram
    autonumber
    participant V as Visitor
    participant S as Sine Platform
    participant I as Integration Endpoint
    participant A as Physical ACS

    V->>S: Check out (or auto check-out / visit expiry)

    alt Digital credential
        S->>I: POST /deprovision
        note right of S: barcode + ACS correlation IDs
        I->>A: Revoke and remove credential
        A-->>I: Credential revoked
    else Deactivate-only mode enabled
        S->>I: POST /deprovision
        note right of S: badgeNumber + ACS correlation IDs<br/>deactivateOnly: true
        I->>A: Deactivate access without hard-delete<br/>(preserve reusable records)
        A-->>I: Credential deactivated
    end

    I-->>S: 200 DEPROVISIONED
```

**Key point:** Deprovision is **non-blocking**. Sine marks the visitor as checked out regardless of whether the Deprovision call succeeds. Failures are logged but the pass is not held in a pending state.

## Check-Out Flow - ACS Initiated (Optional)

When the `Deprovision credential on check-out` setting is enabled in Sine, the Provision request will include a `checkoutUrl` - a callback URL your ACS can call when a visitor badges out at a designated exit reader. Sine will then check the visitor out and trigger Deprovision itself. This flow applies to both credential types.

```mermaid
sequenceDiagram
    autonumber
    participant V as Visitor
    participant A as Physical ACS
    participant S as Sine Platform
    participant I as Integration Endpoint

    V->>A: Present credential at exit reader
    A->>S: POST checkoutUrl with x-sine-api-key header
    note right of A: URL format: .../callbacks/checkout/{jwt}?teamId=...
    S->>S: Validate JWT + check visitor out
    S->>I: POST /deprovision
    note right of S: May include deactivateOnly: true based on workflow
    I->>A: Revoke or deactivate credential
    I-->>S: 200 DEPROVISIONED
```

**Key point:** The `checkoutUrl` includes an authentication token. Your ACS must send this request with the correct `x-sine-api-key` header, or Sine will reject the callback. See [Endpoint Specifications](<./Implementation Guide.mdx>) for the full `checkoutUrl` field specification.

## Responsibilities Summary

| Responsibility                                                       | Sine | Your Integration |
| -------------------------------------------------------------------- | ---- | ---------------- |
| Determining when to provision/activate/deprovision                   | ✓    |                  |
| Sending correctly structured requests with credential type           | ✓    |                  |
| Authenticating outbound requests to your endpoint                    | ✓    |                  |
| Pre-assigning physical card numbers to visitors                      | ✓    |                  |
| Translating Sine requests into ACS API calls                         |      | ✓                |
| Generating unpredictable barcodes for digital credentials            |      | ✓                |
| Deciding how to handle existing card records (physical flows)        |      | ✓                |
| Returning correct response codes and payloads                        |      | ✓                |
| Managing ACS-side credential and cardholder state                    |      | ✓                |
| Handling `deactivateOnly` mode independently of credential type      |      | ✓                |
| Supporting existing credential identifiers in Provision (reuse-safe) |      | ✓                |
| Handling retries for transient ACS failures                          |      | ✓                |
| Validating `checkoutUrl` callback authenticity                       | ✓    |                  |
| Sending the `checkoutUrl` callback from the ACS                      |      | ✓                |

# Core Concepts and Terminology

This section defines the core terms used throughout this manual. Treat these definitions as normative when implementing your endpoint contracts.

## Core Entities

| Term                               | Meaning                                                                                                 | Who owns it                              |
| ---------------------------------- | ------------------------------------------------------------------------------------------------------- | ---------------------------------------- |
| **Visit**                          | The Sine record representing a visitor's time-bounded presence at a site.                               | Sine                                     |
| **Credential**                     | The access token presented at a reader (QR code value, physical card number, virtual credential value). | Shared                                   |
| **Cardholder / Credential holder** | The person record in the ACS linked to one or more credentials.                                         | ACS                                      |
| **Integration endpoint**           | Your HTTPS API that receives ACI calls from Sine and translates them into ACS actions.                  | You                                      |
| **Access group**                   | A logical access-right grouping (for example, Level 2, Car Park, Plant Room).                           | ACS (authoritative), Sine (selected IDs) |

:::BlockQuote
**Terminology note:** Sine uses the term "visitor" throughout this document to refer to the person checking in. In your ACS, the equivalent record may be called a cardholder, person, occupant, employee, or credential holder - the exact term varies by vendor. These are functionally equivalent for ACI purposes.
:::

## Correlation Identifiers

These fields are critical for idempotency, retries, and lifecycle continuity.

| Field                     | Source                                                | Purpose                                                                                        | Stability expectation                    |
| ------------------------- | ----------------------------------------------------- | ---------------------------------------------------------------------------------------------- | ---------------------------------------- |
| `visitId`                 | Sine                                                  | Primary Sine lifecycle key for a visit.                                                        | Stable for entire visit                  |
| `siteId`                  | Sine                                                  | Identifies the Sine location/site context.                                                     | Stable                                   |
| `accessControlVisitId`    | ACS via Provision response                            | ACS-side identifier for the holder/object to use during Activate and Deprovision.              | Must remain reusable in later calls      |
| `accessControlLocationId` | ACS via Provision response                            | Optional ACS location partition key (if needed by vendor API).                                 | Should remain stable for visit lifecycle |
| `barcode`                 | ACS (digital) or Sine (physical via Asset Management) | Credential value presented at readers. Often echoed later as `badgeNumber`.                    | Must refer to the same credential        |
| `badgeNumber`             | Sine                                                  | Explicit credential identifier sent in Activate/Deprovision and physical-card Provision flows. | Must be handled as authoritative input   |

Implementation note:

- Do not assume identifiers are always new.
- Provision may legitimately receive a credential identifier that already exists in the ACS.
- Your endpoint must apply a deterministic policy (match-existing, upsert, or fail with explicit error).

## Credential Types

| Type     | Value      | Typical usage                                             |
| -------- | ---------- | --------------------------------------------------------- |
| Digital  | `digital`  | ACS generates a new QR-compatible value during Provision. |
| Physical | `physical` | Sine sends a pre-assigned physical card identifier.       |
| Virtual  | `virtual`  | Vendor-specific virtual/mobile credential mode.           |

Credential type indicates how the credential should be interpreted, but it does not alone determine deprovision mode. See [Check-Out Flow - Sine Initiated](./#check-out-flow---sine-initiated) for `deactivateOnly` behaviour.

## Lifecycle Operations

| Operation   | Required | Blocking from Sine check-in/check-out flow | Purpose                                                  |
| ----------- | -------- | ------------------------------------------ | -------------------------------------------------------- |
| Verify      | Yes      | N/A                                        | Validate connectivity and API key during setup.          |
| Provision   | Yes      | Yes (blocking)                             | Create or attach credential and return correlation data. |
| Activate    | Yes      | No (non-blocking)                          | Enable credential access in ACS.                         |
| Deprovision | Yes      | No (non-blocking)                          | Revoke or deactivate access at end of lifecycle.         |

## State Language

Use these states consistently in your implementation and logs:

| State         | Practical meaning                                                                                         |
| ------------- | --------------------------------------------------------------------------------------------------------- |
| Provisioned   | Credential/holder exists in ACS and can be referenced, but access may still be disabled until activation. |
| Activated     | Access is enabled and the credential should work at permitted readers.                                    |
| Deprovisioned | Access has been revoked or deactivated according to deprovision mode.                                     |

If your ACS has richer state models, map them internally - but return ACI-compliant success/error responses externally.

## Deprovision Modes

| Mode                 | Trigger                            | Expected ACS action                                                   |
| -------------------- | ---------------------------------- | --------------------------------------------------------------------- |
| Standard deprovision | `deactivateOnly` absent or `false` | Apply your normal revoke/deprovision behaviour.                       |
| Deactivate-only      | `deactivateOnly=true`              | Disable access without destructive deletion required for reuse/audit. |

Important:

- Standard deprovision (full removal) is the default. `deactivateOnly=true` is only sent when a site is explicitly configured for that mode.
- `deactivateOnly` can be configured for any credential type - it is not exclusive to physical card flows.
- If your integration supports deactivate-only mode, ensure your Provision logic handles identifiers that may persist across visits.

## Access Groups

`accessGroups` is the list of ACS group IDs selected in Sine and supplied to your endpoint for entitlement mapping.

Expected handling:

- Treat IDs as opaque ACS identifiers.
- Ignore unknown IDs safely, or fail with a clear validation error if your integration requires strict mapping.
- Keep behaviour consistent and documented for administrators.

## Time Window Fields

| Field       | Meaning                                                                                       |
| ----------- | --------------------------------------------------------------------------------------------- |
| `validFrom` | Effective start timestamp for access. Usually aligns with check-in time.                      |
| `validTo`   | Effective end timestamp derived by Sine policy (invitation/site rules plus any grace period). |

All timestamps should be handled as ISO 8601 UTC values unless otherwise documented by the specific endpoint contract.

## Response Semantics

Successful responses should return an operation-appropriate code (`SUCCESS`, `PROVISIONED`, `ACTIVATED`, `DEPROVISIONED`).

Failure responses should return both:

- A meaningful HTTP status (for example 400, 401, 403, 500)
- A structured body with `code` and `message`

Use consistent, actionable error messages so operators can distinguish payload issues from downstream ACS availability issues.

***

#
