Add health checks
TwilioHealthIndicator reports whether the Twilio API is reachable and your
credentials are still accepted, as a Terminus
health indicator.
Installation
Section titled “Installation”@nestjs/terminus is an optional peer dependency. Install it only if you
want health checks:
npm install @nestjs/terminusImporting
Section titled “Importing”The indicator is exported from the nestjs-twilio/terminus subpath, not
from the package root:
import { TwilioHealthIndicator } from 'nestjs-twilio/terminus';import { Module } from '@nestjs/common';import { TerminusModule } from '@nestjs/terminus';import { TwilioHealthIndicator } from 'nestjs-twilio/terminus';
import { HealthController } from './health.controller';
@Module({ imports: [TerminusModule], controllers: [HealthController], providers: [TwilioHealthIndicator],})export class HealthModule {}import { Controller, Get } from '@nestjs/common';import { HealthCheck, HealthCheckService } from '@nestjs/terminus';import { TwilioHealthIndicator } from 'nestjs-twilio/terminus';
@Controller('health')export class HealthController { constructor( private readonly health: HealthCheckService, private readonly twilio: TwilioHealthIndicator ) {}
@Get() @HealthCheck() check() { return this.health.check([() => this.twilio.isHealthy('twilio').withTimeout(5000)]); }}A healthy response:
{ "status": "ok", "info": { "twilio": { "status": "up", "accountSid": "ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "friendlyName": "My Twilio Account", "responseTime": 143 } }, "error": {}, "details": { "twilio": { "status": "up", "responseTime": 143 } }}What the check does
Section titled “What the check does”It fetches the client’s own Account resource, which exercises both network reachability and credential validity in a single call.
The indicator reports down when:
- the request fails: network error, invalid credentials, Twilio outage
- the account status is not
active, i.e.suspendedorclosed
A suspended account still authenticates but cannot send anything, so treating it as healthy would be misleading.
Checking named clients
Section titled “Checking named clients”Pass a client as the second argument to probe a client registered with
registerClient():
@Controller('health')export class HealthController { constructor( private readonly health: HealthCheckService, private readonly twilio: TwilioHealthIndicator, @InjectTwilio('billing') private readonly billing: TwilioClient ) {}
@Get() @HealthCheck() check() { return this.health.check([ () => this.twilio.isHealthy('twilio').withTimeout(5000), () => this.twilio.isHealthy('twilio-billing', this.billing).withTimeout(5000), ]); }}With no argument the default client from forRoot() is used. If no client is
registered at all, the indicator reports down with guidance rather than
throwing.
Timeouts
Section titled “Timeouts”isHealthy() returns Terminus’ attempt builder, so withTimeout() and
cacheFor() chain as they do for any indicator.
Every Twilio health check is a real API request. Use cacheFor() if your
orchestrator probes frequently:
() => this.twilio.isHealthy('twilio').withTimeout(5000).cacheFor(30_000);Failure reporting
Section titled “Failure reporting”The indicator is built on Terminus’ attempt(), not up()/down(). That
distinction matters: an indicator written with up()/down() that throws
aborts the entire health check and returns 500, whereas attempt()
translates a thrown error into a down result and the expected 503.
With invalid credentials you get:
{ "status": "error", "error": { "twilio": { "status": "down", "message": "Authentication Error - invalid username", "responseTime": 412 } }}