A small, self-hosted Twilio application that gives one person a dedicated phone number for urgent calls. Calls to the dedicated number are forwarded to the owner’s mobile phone using the dedicated number as caller ID. On an iPhone, saving that number as a contact with Emergency Bypass enabled can make it ring through Silent mode or a Focus.
The project intentionally has no accounts, customer database, payment system, or caller allowlist. Each person deploys and pays for their own Twilio resources.
Warning
This is not 911, 112, or an emergency service. It provides no guarantee that a call, text, alert, or voicemail will be delivered, heard, or answered. Twilio, mobile carriers, the internet, account balance, software, phone settings, and the destination phone can all fail. Always keep another way to reach the owner, and contact local emergency services when immediate assistance is needed.
Documentation:
- Configuration and credential setup
- Operations, monitoring, costs, and teardown
- SMS and US A2P registration
- Upgrading and rollback
For a normal inbound call, the deployed Function:
- dials the configured mobile phone for 18 seconds;
- retries once if the first dial is not completed;
- offers a voicemail if neither dial completes; and
- optionally sends the owner a missed-call or voicemail text.
Inbound human-authored texts are never relayed. Automated missed-call and voicemail alerts are off by default because US application-to-person messaging usually requires the deployer’s own carrier registration. Voice forwarding works independently of SMS. SMS_ENABLED=false does not make a Twilio number incapable of receiving carrier SMS; inbound texts are always discarded by the application but may still create Twilio/carrier usage.
Anyone who knows the dedicated number can call it. They can also send texts, which the application discards but which may still create Twilio/carrier usage. There is intentionally no trusted-caller list. Treat both active and synthetic-test numbers as private: unwanted traffic can make the phone ring or create Twilio charges.
- Emergency Bypass is an Apple device feature, not a Twilio feature. It does not force maximum volume. Keep the ringer audible and test the exact phone and contact regularly.
- A completed forwarded call can be a person or the mobile carrier’s voicemail. The application cannot reliably distinguish them.
- The synthetic checks do not prove that the owner’s physical phone rang. Perform a real by-ear ring test at least monthly.
- The provisioning flow is designed around US Twilio local numbers and iPhone Emergency Bypass. Other countries, number types, phones, and carriers may behave differently.
- GitHub can disable scheduled workflows in inactive public repositories. Do not rely on GitHub Actions as the only alarm channel.
- Voicemail records callers. The deployer is responsible for notice, consent, retention, deletion, and all laws and carrier rules that apply to their deployment.
Running this project creates charges in your Twilio account. Setup normally purchases two local numbers: the dedicated line and a synthetic-test line. Calls can incur an inbound leg and a simultaneous outbound leg; retries, SMS segments, recordings, recording storage, carrier fees, registration, Functions usage, and monitoring can add charges. Twilio pricing and carrier rules change, so review Twilio’s current Voice pricing, Messaging/A2P pricing, and the fuller cost model before proceeding.
For a concrete reference, this is an example US pay-as-you-go budget using public prices checked on July 13, 2026, with the A2P Brand fee rechecked July 20. It is an estimate, not a quote; Twilio can change prices, rounds each call leg separately, and may add carrier fees and taxes.
| Service or resource | Example assumption | Approximate cost |
|---|---|---|
| Twilio local numbers | One active line plus one synthetic-test line at 1ドル.15 each | 2ドル.30/month |
| Forwarded voice calls | 0ドル.0085/min inbound plus 0ドル.0140/min outbound | 0ドル.0225/connected minute |
| Synthetic voice monitoring | Supplied M3 check enabled twice daily; about 60 one-minute, two-leg calls/month | 1ドル.35/month |
| Twilio Functions | First 10,000 invocations/month are free; then 0ドル.0001/invocation | Usually 0ドル at light personal usage. One request every 5 minutes is about 8,640/month; four regional requests at that cadence would be about 34,560/month, or about 2ドル.46 beyond the allowance |
| GitHub Actions monitoring | Standard GitHub-hosted runner in a public repository | 0ドル |
| External HTTP monitor | Optional; Better Stack and similar providers may offer a sufficient free tier | Often 0ドル; provider-dependent |
| Call recording | Recording plus retained storage | 0ドル.0025/min + 0ドル.0005/stored min/month |
| SMS traffic, if enabled | US long-code inbound or outbound SMS | 0ドル.0083/segment + carrier fees |
| Sole Proprietor A2P, if needed for US SMS | 4ドル.50 Brand registration and 15ドル Campaign vetting; then 2ドル/month | About 19ドル.50 once + 2ドル/month |
That makes the example voice-only baseline about 3ドル.65/month with both numbers and the twice-daily synthetic check, before real calls, recordings, taxes, and optional external monitoring. Adding the example Sole Proprietor A2P campaign makes the recurring baseline about 5ドル.65/month, before actual SMS traffic. A voice-only deployment with automated synthetic calls disabled starts around 2ドル.30/month before real usage. See Twilio’s current Voice, SMS, Serverless, and A2P fee pages before deployment.
Recommended safeguards:
- use a dedicated Twilio subaccount for this deployment;
- enable Twilio balance auto-recharge and a low-balance alert;
- configure Twilio usage triggers or other spending alerts, understanding that notifications are not hard spending caps;
- keep SMS disabled until registration and real delivery tests pass;
- keep the dedicated number private; and
- review usage and perform a real ring test every month.
The CLI shows a resource/cost warning and requires confirmation before buying or releasing numbers. Treat --yes as a billable/destructive automation switch, not as a harmless convenience.
- Node.js 22
- a paid Twilio account that can purchase a local number
- preferably, a dedicated Twilio subaccount
- a Twilio Standard API key for that subaccount
- the subaccount Auth Token for deploying and signing the local Function probe
- an iPhone if you want to use Apple Emergency Bypass
- OpenSSL or another cryptographically secure random-string generator for
HEALTH_TOKEN - ripgrep (
rg) if you use the optional legal-template placeholder check
Never put a real number, credential, provider resource ID, or private webhook URL in a committed file. .env, Twilio deployment state, generated compliance pages, and operator notes are ignored by Git.
Read Configuration before creating credentials. Use a dedicated account/subaccount for this deployment when possible. INSTANCE_ID isolates the CLI’s number tags, but the deployment wrapper still uses a fixed Twilio Serverless Service name; multiple installations should not share that Service.
git clone https://github.com/ankitgoyal100/emergency-line.git cd emergency-line npm ci npm test cp .env.example .env
If you use a fork, clone your reviewed fork instead. For a live installation, prefer a release tag or exact commit you reviewed over an unpinned moving branch. Confirm that Node is version 22. Fill .env with credentials and configuration from the dedicated Twilio account/subaccount. Set a stable, unique INSTANCE_ID (lowercase letters, numbers, and internal hyphens) so the CLI manages only this installation’s number tags. Do not change it after provisioning. Leave TEST_NUMBER blank until setup purchases it, and keep SMS_ENABLED=false. Replace every example value; the CLI deliberately rejects example credentials and numbers. Generate a long health token:
openssl rand -hex 24
Bootstrap is intentionally two-stage: the first deployment creates the Function URL without a test number; setup then purchases and wires the active/test numbers; the second deployment teaches the Function which caller must be routed to the non-ringing synthetic sink. The /health endpoint is expected to report voice as not ready between those stages.
-
Validate the deployment inputs without changing Twilio, then explicitly deploy the Functions:
npm run deploy -- --dry-run npm run deploy -- --yes
-
Put the printed HTTPS service URL in
FUNCTION_URLin.env. -
Review the setup plan without purchasing anything:
npm run setup -- --dry-run
-
Run setup and read its cost/resource preview carefully:
npm run setup
Setup is billable. It should not purchase numbers until you explicitly confirm.
Setup attempts to release numbers bought by the current invocation if a later purchase/configuration step fails. If the error says cleanup failed, inspect Twilio immediately: the reported number may still be allocated and billable.
-
Put the returned synthetic-test number in
TEST_NUMBER, then deploy again:npm run deploy -- --dry-run npm run deploy -- --yes
-
Save the dedicated line as a contact on the destination iPhone. For both Ringtone and Text Tone, enable Emergency Bypass, choose an audible tone, and keep the ringer volume up.
Continue directly to the validation ladder below. It contains the deliberate billable tests; do not run them twice or share the number before they pass.
Run checks from least consequential to most consequential. None of these commands is a guarantee of future delivery.
-
Inspect the private local/provider state. Do not paste this output publicly because it contains numbers and URLs:
npm run status npm run check:config npm run check:function
check:configreads Twilio configuration and balance.check:functionsends a signed HTTP request to the deployed Function and verifies the forwarding destination; it does not place a call. -
Deliberately run the billable synthetic route check. Its signed preflight must prove that the exact tagged test caller is sunk before the command originates anything:
npm run check:e2e -- --yes
This tests Twilio’s call path into the Function without intentionally ringing the owner. It does not verify the physical phone.
-
From a separate, non-test phone, call the dedicated line. Confirm the intended phone rings, answer, and verify two-way audio.
-
Deliberately run
npm run ring-test, type its confirmation, and verify the saved contact/device behavior by ear. This is a separate billable call and does not test the inbound forwarding path. -
Test the unanswered path: verify the retry and recording notice. With SMS disabled, no missed-call/voicemail text is sent; inspect and manage recordings in Twilio according to your retention obligations.
Repeat the physical-phone checks after device/contact changes, carrier changes, number changes, or application rollback—not only after initial setup.
Leave SMS_ENABLED=false for a voice-only deployment. Before enabling SMS, the deployer must complete their own registration, consent disclosures, sender assignment, and delivery tests. Do not copy another operator’s campaign IDs, attestations, legal text, or consent claims.
If enabled, SMS is limited to automated missed-call and voicemail notifications to the configured owner; inbound human-authored text is never relayed. See SMS and US A2P registration and the neutral legal templates. Run npm run sms-readiness once as a provider preflight while disabled and again after enabling and completing real notification/no-relay/STOP/START/HELP tests. Those human confirmations make no provider changes and are not proof of compliance. The templates are starting points, not legal advice and not evidence that consent occurred.
| Command | Purpose | Network/cost impact |
|---|---|---|
npm test |
Run the offline test suite | None |
npm run deploy -- --dry-run |
Validate deploy inputs without replacing the Function | Local only |
npm run deploy -- --yes |
Replace the active Twilio Functions build | Live deployment mutation |
npm run setup -- --dry-run |
Validate configuration and preview resources | Read-only |
npm run setup |
Purchase missing numbers or rewire existing tagged numbers after exact confirmation | Billable or live configuration mutation |
npm run status |
Show deployment configuration and account balance | Read-only Twilio API calls |
npm run ring-test |
Place a real test call to the owner’s phone | Billable call |
npm run swap -- --dry-run |
Preview a replacement-number operation | Read-only Twilio API calls |
npm run swap |
Buy a replacement line and stage it for human verification | Billable and potentially destructive |
npm run check:function |
Probe the deployed forwarding TwiML | Network request; does not ring the phone |
npm run check:config |
Check webhooks and account balance | Read-only Twilio API calls |
npm run check:e2e -- --yes |
After a non-ringing sink preflight, call from the test line into the dedicated line | Billable synthetic call |
npm run sms-readiness |
Require exact human confirmation of approval, sender, webhook, notification delivery, no-relay, HELP, STOP/blocked, and START/restored checks | Read-only; makes no provider changes |
npm run release-numbers -- --dry-run |
Preview the tagged active/test numbers that would be released | Read-only |
npm run release-numbers |
Release this deployment’s tagged active/test numbers | Destructive |
swap must not release the old line based only on a synthetic test. Confirm the new contact and a real physical-phone ring before approving release of the old number. If cleanup fails, use npm run status and the Twilio Console to look for duplicate or provisional numbers.
--yes bypasses the initial setup, swap, or number-release confirmation and should be reserved for intentional automation. ring-test accepts no flags and always requires the exact CALL confirmation. No automation flag turns a synthetic test into proof of a physical ring, and swap still requires the separate RANG and old-number release confirmations.
The repository includes four different checks:
/healthis a token-protected provider check for exact tagged-number inventory, test-number identity, voice/SMS webhook drift, HTTP methods, Twilio account status, and a balance of at least 5ドル. It does not place a call or send a text.check:configchecks both retained numbers’ webhook configuration and the account balance.check:functionasks the deployed Function for forwarding TwiML and verifies the destination. It does not place a call.check:e2efirst sends a signed, non-ringing webhook probe and refuses to originate when the deployed Function does not prove that the exact tagged test number will be sunk. With explicit--yes, it then places a billable synthetic call from the test number to the dedicated number.
For the non-ringing baseline, prefer an independent HTTPS monitor that requests /health and requires both HTTP 200 and the exact success marker emergency-line-m1-ok. This removes GitHub's scheduler from the basic availability alarm path. The included GitHub Actions monitor separately runs configuration and billable synthetic checks, but scheduled workflows may be delayed or dropped. Forks do not inherit secrets. If you use it, configure the repository secrets named in .github/workflows/monitor.yml; when INSTANCE_ID is set locally, add a matching INSTANCE_ID repository secret as well. Enable Actions failure notifications and review scheduled-workflow status periodically.
No automated check verifies the owner’s speaker, volume, contact, battery, mobile service, or attention. Keep a recurring reminder for the physical ring test.
See Operations for swapping, monitoring, incident checks, backups, costs, and complete teardown. See Upgrading and rollback before replacing a live Function build. Releasing Twilio numbers is irreversible and does not remove recordings, logs, Functions, Messaging Services, registrations, monitors, or GitHub secrets. Confirm each provider separately.
functions/contains the Twilio call, SMS, health, TwiML, and message handlers.src/contains the local provisioning and number-management CLI.monitor/contains read-only configuration/Function checks and the synthetic call check..github/workflows/contains CI and optional scheduled monitoring.
The owner’s laptop is not in the live call path after deployment. Twilio hosts the call logic; optional GitHub Actions and an uptime provider host monitoring.
Read SECURITY.md before reporting a vulnerability. General contribution guidance is in CONTRIBUTING.md, and the project’s best-effort support policy is in SUPPORT.md.
Licensed under the MIT License.
This project is not affiliated with or endorsed by Twilio Inc. Twilio and related marks belong to Twilio Inc. or its affiliates.