Testing & Deployment
Integration Registration and Configuration
ACI integrations are set up by a Sine team member in the Sine platform on your behalf. You do not configure the integration directly - instead, you provide your endpoint URLs and API key to your Sine contact, who will configure and test the integration in a Sine environment for you.
What to Prepare
Before your setup session with Sine, have the following ready:
Item | Description |
|---|---|
Endpoint URLs | HTTPS URLs for your Verify, Provision, Activate, and Deprovision endpoints. These must be internet-accessible from Sine's cloud. For local development, use a tunnelling tool such as ngrok. |
API key | A secret key your endpoint will use to authenticate incoming requests from Sine. You generate this on your side. Sine sends it as the Authorization header on every request. |
Access Groups URL | Optional. The HTTPS URL for your Access Groups endpoint, if supported. |
Credential type | Whether your integration supports digital, physical, or virtual credentials. |
External ID | Optional. A reference string your integration can use to identify the site or configuration context. Sine includes this in every request body if configured. |
Configuration Reference
The following fields are configured in Sine during setup. Understanding what each field does is important because they directly affect the requests your integration receives.
Endpoint URLs
Setting | Required | Effect |
|---|---|---|
Verify endpoint | Yes | Called during setup and connectivity checks. |
Provision endpoint | Yes | Called on visitor check-in. |
Activate endpoint | Yes | Called after approval checks complete. |
Deprovision endpoint | Yes | Called on check-out or visit expiry. |
Access Groups endpoint | No | Enables access group selection in Sine's configuration UI. |
Credential Behaviour
Setting | Required | Effect on your integration |
|---|---|---|
Credential type | Yes | Determines whether Sine sends a badgeNumber (physical) or expects a generated barcode in the Provision response (digital/virtual). |
Provision on check-in | Yes | Controls which visitor types trigger a Provision call. |
Deprovision on check-out | No | When enabled for a visitor type, Sine calls Deprovision on checkout. Also causes checkoutUrl to be included in the Provision request body. |
Grace period | No | Extends validTo beyond the pass end time by a configured number of minutes. Your ACS should honour the validTo value in the request. |
Failure Handling
Setting | Effect |
|---|---|
Visitor failure message | Displayed to the visitor in Sine if Provision fails. |
Failure notification email list | Email addresses notified when lifecycle calls fail. |
Optional Features
Setting | Effect |
|---|---|
External ID | A free-text string (max 256 characters) sent in every request body. Useful for mapping a Sine site to a reference in your own system. |
Send QR by SMS | When enabled, Sine sends the provisioned QR credential to the visitor's mobile number via SMS. No change to your endpoint contract. |
Secure Bridge | An alternative to public endpoints. Routes Sine requests through an encrypted tunnel to your local network. Contact your Sine representative for details. |
How Sine Authenticates to Your Endpoint
Sine sends your configured API key as the Authorization header on every lifecycle request:
Authorization: <your-api-key>Your endpoint must validate this header on every request and return 401 if it is absent or does not match.
Branded Integrations
If your integration is intended for distribution - for use by multiple Sine customers rather than a single site - Sine can brand it under your company or product name. Branded integrations appear in the Sine integrations list under your name rather than as a generic "Access Control" configuration.
To set up a branded integration, provide your Sine representative with the following:
Item | Details |
|---|---|
Integration name | Your preferred display name as it should appear in the Sine integrations list. |
Icon | A 256×256 PNG image. Used as the integration's logo in the Sine interface. |
Endpoint URLs | The specific URL for each required endpoint (Verify, Provision, Activate, Deprovision) and optionally Access Groups. |
Regional endpoints | If your platform operates across multiple regions (for example, a US domain and an EU domain), provide the endpoint URLs for each region. Sine will configure region-specific variants so that customer data stays within the appropriate geography. |
Contact your Sine representative to discuss the requirements and process for a branded integration.
Testing Your Integration
Testing an ACI integration has two distinct phases: testing your endpoint directly (before Sine is involved) and testing the full end-to-end flow through a Sine test environment.
Testing with a Sine Test Environment
Once your Sine contact has configured the integration in a test environment, you can trigger the full lifecycle by performing a real check-in and check-out through Sine.
What to test:
Scenario | How to trigger | What to verify |
|---|---|---|
Provision called on check-in | Check a visitor in at the configured site | Endpoint receives Provision request; returns PROVISIONED with correct barcode and accessControlVisitId |
Activate called after check-in | Check in completes (Activate is automatic) | Endpoint receives Activate with the badgeNumber from Provision response; returns ACTIVATED |
Deprovision called on check-out | Check the visitor out | Endpoint receives Deprovision; credential is revoked in ACS |
Deactivate-only mode | Check out with deactivateOnly configured | Endpoint receives ?deactivateOnly=true; credential is disabled but not deleted |
ACS-initiated checkout | Configure exit reader callback; visitor badges out | ACS posts to checkoutUrl; Sine checks visitor out and calls Deprovision |
Verify | Use the test/verify action in Sine's integration settings | Endpoint receives Verify; returns SUCCESS |
Recommended check-in path for testing:
- In your Sine test environment, go to Locations → select your site → Integrations → open the configured Access Control integration.
- Use the Test or Verify button to confirm connectivity before performing a full check-in.
- Check in a test visitor. Watch your endpoint logs for the incoming Provision request.
- Confirm the credential was created in your ACS in an inactive state.
- Confirm the Activate request arrives shortly after, and access is enabled.
- Check out the visitor. Confirm Deprovision fires and the credential is revoked in your ACS.
Tips:
- Use a tool like ngrok to expose a local endpoint during development. Your Sine contact can configure the integration to point to your ngrok URL.
- Log the full request body (excluding the Authorization header value) on every incoming request - this makes debugging lifecycle issues significantly easier.
- Test idempotency: call each endpoint twice with the same payload and confirm the second call returns the correct success response without creating duplicate records.
Sending Mock Requests Directly
You can test your endpoint contract without a Sine environment by sending HTTP requests directly. This is useful for verifying your request parsing, authentication checks, and response shapes early in development.
The examples below use curl. Replace https://your-endpoint.example.com with your actual URL and your-api-key with the key you have configured.
Verify
curl -X POST https://your-endpoint.example.com/verify \
-H "Authorization: your-api-key" \
-H "Content-Type: application/json" \
-d '{"externalId": "test-site"}'Expected response:
{ "code": "SUCCESS" }Provision (digital credential)
curl -X POST https://your-endpoint.example.com/provision \
-H "Authorization: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"visitId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"siteId": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"credentialType": "digital",
"validFrom": "2026-05-26T09:00:00.000Z",
"validTo": "2026-05-26T17:00:00.000Z",
"visitor": {
"firstName": "Test",
"lastName": "Visitor",
"email": "[email protected]"
}
}'Expected response:
{
"code": "PROVISIONED",
"data": {
"barcode": "<unpredictable-credential-value>",
"accessControlVisitId": "<your-acs-holder-id>"
}
}Activate
curl -X POST https://your-endpoint.example.com/activate \
-H "Authorization: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"visitId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"siteId": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"credentialType": "digital",
"accessControlVisitId": "<value-from-provision-response>",
"badgeNumber": "<barcode-from-provision-response>"
}'Expected response:
{ "code": "ACTIVATED" }Deprovision
curl -X POST https://your-endpoint.example.com/deprovision \
-H "Authorization: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"visitId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"siteId": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"credentialType": "digital",
"accessControlVisitId": "<value-from-provision-response>",
"badgeNumber": "<barcode-from-provision-response>"
}'Expected response:
{ "code": "DEPROVISIONED" }Testing authentication rejection
Confirm your endpoint returns 401 for a missing or invalid API key:
curl -X POST https://your-endpoint.example.com/verify \
-H "Authorization: wrong-key" \
-H "Content-Type: application/json" \
-d '{}'Expected response: HTTP 401 with a structured error body.
Validation Checklist
Use this checklist before going live or handing off to your Sine contact for integration testing.
Authentication
Endpoint returns 401 for missing Authorization header
Endpoint returns 401 for an incorrect API key
API key is stored securely and not logged or committed to version control
Verify
Returns { "code": "SUCCESS" } with HTTP 200
Completes quickly (under 2 seconds)
Provision
Returns { "code": "PROVISIONED", "data": { ... } } with HTTP 201
data.barcode is present and non-empty
data.accessControlVisitId is present and non-empty
For digital credentials: barcode is unpredictable (non-sequential, non-guessable)
For physical credentials: barcode echoes the badgeNumber sent in the request
Credential is created in ACS in an inactive/disabled state (does not grant access yet)
Calling Provision twice with the same visitId returns PROVISIONED without creating duplicates
Response time is consistently under 5 seconds (blocking check-in path)
Activate
Returns { "code": "ACTIVATED" } with HTTP 200
Credential in ACS grants access after Activate is called
Calling Activate twice with the same identifiers returns ACTIVATED (idempotent)
Deprovision
Returns { "code": "DEPROVISIONED" } with HTTP 200
Credential in ACS no longer grants access after Deprovision
Calling Deprovision twice with the same identifiers returns DEPROVISIONED (idempotent)
deactivateOnly=true disables access without hard-deleting ACS records (if supported)
Error handling
Invalid or missing required fields return 400 with a structured error body
Downstream ACS unavailability returns 5xx (not a silent success)
Error response body follows { "code": "REQUEST_FAILED_ERROR", "message": "..." } shape
Error messages are actionable - they describe what failed and whether a retry is likely to help
Access Groups (if implementing)
/access-groups returns { "results": [...] } with HTTP 200
Each result includes id and name
nameIncludes filtering works case-insensitively (or returns full list if filtering unsupported)
nextLink is included when more results exist and is directly callable