---
title: "How to Track Opt-Outs in PHP"
description: "This tutorial demonstrates building a PHP application that records customer opt-out preferences from SMS replies using Twilio’s Incoming Message Webhook and Event Streams, which require PHP 8.5, Composer, and SQLite. When the SMS body is an opt-out keyword such as STOP, START, or HELP, Twilio includes an OptOutType parameter in the webhook request, which the application checks using strcasecmp and array_first. The application, based on the Twilio Slim Base project, stores the opt-out status and account SID in an SQLite database via PHP-DB and laminas-servicemanager, using a TableGateway for the user_optouts table. The handleWebhook() function validates the OptOutType against class constants (OPT_OUT_TYPE_START, OPT_OUT_TYPE_STOP, OPT_OUT_TYPE_HELP) and inserts a record before returning a TwiML response. Twilio already blocks further messages for standard opt-outs, but local recording enables advanced actions like syncing a CRM; the tutorial covers bootstrapping, configuring Twilio messaging services with Advanced Opt-Out, using ngrok, and verifying with an SQL query."
---

# How to Track Opt-Outs in PHP

[Twilio](https://yomu.fyi/company/twilio) · Matthew Setter · Oct 2, 2026

**Type:** Tutorial

## Summary

This tutorial demonstrates building a PHP application that records customer opt-out preferences from SMS replies using Twilio’s Incoming Message Webhook and Event Streams, which require PHP 8.5, Composer, and SQLite. When the SMS body is an opt-out keyword such as STOP, START, or HELP, Twilio includes an OptOutType parameter in the webhook request, which the application checks using strcasecmp and array\_first. The application, based on the Twilio Slim Base project, stores the opt-out status and account SID in an SQLite database via PHP-DB and laminas-servicemanager, using a TableGateway for the user\_optouts table. The handleWebhook() function validates the OptOutType against class constants (OPT\_OUT\_TYPE\_START, OPT\_OUT\_TYPE\_STOP, OPT\_OUT\_TYPE\_HELP) and inserts a record before returning a TwiML response. Twilio already blocks further messages for standard opt-outs, but local recording enables advanced actions like syncing a CRM; the tutorial covers bootstrapping, configuring Twilio messaging services with Advanced Opt-Out, using ngrok, and verifying with an SQL query.

## Context

Tracking customer opt-outs from SMS communications is essential for compliance with privacy laws like the Australian Spam Act and CAN-SPAM Act. Twilio provides opt-out detection via webhooks and event streams, but recording preferences locally allows for advanced actions such as CRM synchronization.

## Approach / What changed

Build a PHP application based on the Twilio Slim Base project. Update the handleWebhook() function to extract the OptOutType parameter from incoming webhook or event stream requests using strcasecmp and array\_first. Validate against class constants (OPT\_OUT\_TYPE\_START, OPT\_OUT\_TYPE\_STOP, OPT\_OUT\_TYPE\_HELP) and insert a record into an SQLite database via PHP-DB and laminas-servicemanager. Configure Twilio messaging service to use the webhook URL and enable Advanced Opt-Out. Optionally configure Event Streams for the inbound message received event. Test by sending an SMS with an opt-out keyword and verify the database record.

## Takeaways

- Twilio’s Incoming Message Webhook and Event Streams include an OptOutType parameter when the SMS body is an opt-out keyword like STOP, START, or HELP.
- Recording opt-out preferences locally in a database allows advanced actions such as keeping a CRM in sync, beyond Twilio’s built-in blocking.
- The application uses PHP-DB with laminas-servicemanager to store opt-out records in an SQLite table, and the handleWebhook() function validates the OptOutType against class constants.

## FAQ

### How does Twilio indicate an opt-out in webhook requests?

Twilio includes an OptOutType parameter in the request body when the SMS body is an opt-out keyword such as STOP, START, or HELP. The application checks for this parameter using strcasecmp and array\_first.

### What are the allowed opt-out keywords in this tutorial?

The tutorial defines three constants: OPT\_OUT\_TYPE\_START, OPT\_OUT\_TYPE\_STOP, and OPT\_OUT\_TYPE\_HELP, corresponding to the keywords START, STOP, and HELP. The list can be expanded as needed.

### Why record opt-outs locally when Twilio already blocks messages?

Twilio blocks further messages for standard opt-outs, but local recording enables more advanced actions like syncing a CRM or applying custom business logic based on opt-out preferences.

**Tags:** [Opt-Out](https://yomu.fyi/topic/opt-out), [PHP](https://yomu.fyi/topic/php), [SMS](https://yomu.fyi/topic/sms), [SQLite](https://yomu.fyi/topic/sqlite), [Twilio](https://yomu.fyi/topic/twilio)

- Source: [Twilio](https://www.twilio.com/en-us/blog/developers/tutorials/track-opt-outs-in-php)
- Source URL: https://www.twilio.com/en-us/blog/developers/tutorials/track-opt-outs-in-php
- Ingested by Yomu: 2026-10-03T03:00:11.917Z

[Read original post](https://www.twilio.com/en-us/blog/developers/tutorials/track-opt-outs-in-php)
