📚 Documentation
After Hours Contact — v1.0.0
Prerequisites
Before setting up After Hours Contact you will need:
- A Twilio account — twilio.com. A free trial account works for testing.
- A Twilio phone number with Voice capability. This becomes the number customers call after hours.
- A publicly accessible URL for the app so Twilio can deliver webhooks. For local testing, use ngrok or a similar tunnel.
- Windows hosting — IIS on Windows Server, or run as a Windows Service. The app is self-contained and does not require .NET to be pre-installed.
First-Run Setup
appsettings.json before the app starts.
-
Open
appsettings.json(orappsettings.Production.json) and fill in your Twilio credentials under theAppSettingssection:"AppSettings": { "TwilioAccountSid": "ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "TwilioAuthToken": "your_auth_token", "TwilioFromPhone": "+15550001234", "TwilioMessagingServiceSid": "" // optional } - Start the app. It detects the empty database and redirects to
/setupautomatically. -
On the setup page, enter your name, email address, and
mobile phone number (E.164 format, e.g.
+15550001234), then click Create Admin Account. -
The setup page automatically reads the Twilio credentials from
appsettings.jsonand stores them in the database. You will receive an SMS code at the phone number you entered. - Sign in with your email. Enter the code from the SMS. You land on the Dashboard.
After the initial setup you can update Twilio credentials at any time via Settings → Twilio Credentials without editing any files.
License Registration
After Hours Contact includes a 14-day trial. During the trial, a small notice appears on the admin dashboard. No functionality is restricted.
To obtain a license:
- Go to /register in the app. Ensure your Twilio Account SID is already saved in Settings (the page needs it to generate your unique Account ID Hash).
- Fill in your name, company (optional), and email address, then click Generate Request.
- Copy the resulting JSON and email it to licenses@afterhours.contact.
- You will receive a
license.licfile by email within one business day. - Return to /register and upload the file using the Step 2 form.
Twilio Configuration
Twilio credentials are configured in appsettings.json before first run (see
First-Run Setup above) and are then stored in the database automatically.
To update credentials after initial setup, go to Settings → Twilio Credentials and enter:
- Account SID — found on your Twilio Console dashboard.
- Auth Token — found on the same page (click to reveal).
- From Phone Number — your Twilio number in E.164 format (e.g.
+15550001234). - Messaging Service SID — optional. Recommended for SMS deliverability. Create one at Twilio Console → Messaging → Services.
Click Save Credentials, then use the Send Test SMS to Me button to verify connectivity.
Twilio Webhook URLs
In the Twilio Console, configure your phone number’s webhook URLs to point to this app:
- Voice → A call comes in:
https://your-domain/voice/incoming(HTTP POST) - Voice → Call Status Changes:
https://your-domain/voice/call-status(HTTP POST)
Replace your-domain with the value you set in Settings → Base URL.
Setting Up the Schedule
Navigate to Schedule (admin only). Each row represents one on-call period. Select a team member from the dropdown and click Save, or use Save All to commit multiple rows at once.
Rotation Settings
Under Settings → Schedule Rotation you can configure:
- Period — Weekly, bi-weekly, 4-week, or custom.
- Starts On — Which day of the week a period begins.
- At Time — The hour on that day when the rotation switches (Eastern time).
Adding Team Members
Go to Users to add on-call staff. Each user needs a valid mobile phone number (E.164 format). Optionally assign a Supervisor — if a user does not acknowledge after the configured number of retries, their supervisor is called instead.
How Calls Work
- Caller dials your Twilio number.
- During business hours: the caller hears your business hours message and the call ends. Configure business hours under Settings → Business Hours.
- After hours: the caller hears the after-hours greeting and is prompted to leave a voicemail.
- Voicemail recorded: the system immediately calls and texts the on-call person. The SMS includes the caller’s number and a link to the recording. The voice call plays back the recording and prompts press 1 to acknowledge.
- Not answered: after the retry interval (default 5 minutes), the system calls again. The number of attempts before escalating to the supervisor is configured under Settings → Notification & Retry.
- Supervisor escalation: if the on-call person never acknowledges, the supervisor is called. If the supervisor also does not answer after the same number of retries, the incident is marked Failed.
- Acknowledged: whoever presses 1 closes the incident. The Incidents page records whether it was the on-call person or the supervisor who acknowledged.
Managing Users
Admins manage users under the Users page. Each user has:
- Name and email (used for login).
- Mobile phone number in E.164 format — used for calls and SMS.
- Role — Admin (full access) or User (own incidents and schedule only).
- Supervisor — optional. If set, this person receives escalation calls when the user doesn’t answer.
Users sign in with their email address and a one-time SMS code. No passwords are stored.
Microsoft Entra ID (Azure AD)
After Hours Contact uses its own SMS-based authentication — users sign in with their email and a one-time code sent to their mobile phone. This requires no integration with Microsoft Entra ID and works independently of your organization’s identity platform.
Hosting in an Entra / Azure environment
The app runs on standard Windows hosting and has no Azure dependency. Supported environments include:
- On-premise IIS — domain-joined server, Entra-managed or standalone.
- Azure VM — Windows Server with IIS, Entra-joined or workgroup.
- Azure App Service — works as-is; set the runtime stack to ASP.NET Core.
- Windows Service — runs headlessly, useful for servers without IIS.
No special Entra configuration is required for any of these hosting modes. If the app is on an Entra-joined machine, you can run it under a Group Managed Service Account (gMSA) for tighter security — set the service account in IIS Application Pool identity or the Windows Service logon.
Controlling who can log in
Access is managed entirely within After Hours Contact. Add users via the Users page and assign them a role (Admin or User). Only users with a record in the system can sign in, regardless of whether they have an Entra account.
There is no Entra SSO integration in the current version. All authentication goes through the SMS code flow. If your organization requires Entra SSO, contact support@afterhours.contact to discuss a custom integration.
Conditional Access considerations
Because After Hours Contact does not authenticate through Entra, it is not subject to Conditional Access policies applied to Entra-registered apps. If your organization requires all web apps to be registered with Entra, you can register After Hours Contact as a public client / native app in Azure — users will still authenticate via SMS code within the app, not via the Entra login flow.
Troubleshooting
Twilio webhooks are not reaching the app
- Confirm Base URL in Settings matches the public URL Twilio is sending to.
- The URL must be HTTPS and publicly reachable. For local testing use ngrok.
- Check Twilio Console → Monitor → Errors for webhook delivery failures.
On-call person is not being called
- Confirm the current period has someone assigned on the Schedule page.
- Check that the user’s phone number is in E.164 format and is a valid mobile number.
- Verify Twilio credentials are saved correctly (use the Send Test SMS button).
SMS is not being received
- If using a Messaging Service SID, confirm it is active in Twilio Console.
- If using a From Phone Number directly, confirm it has SMS capability.
- Check Twilio Console → Monitor → Logs → Messages for delivery status.
Login SMS code not arriving
- Verification codes expire after 10 minutes.
- Confirm your phone number in the Users page exactly matches what you are receiving SMS on (E.164 format).
- Check Twilio logs as above.
License upload fails
- Ensure your Twilio Account SID is saved in Settings before uploading the license.
- The license is tied to the Account SID hash provided in your license request. If you change Twilio accounts, you will need a new license.
- Email licenses@afterhours.contact if the problem persists.
Still stuck? We’re happy to help.
support@afterhours.contact