PHPackages                             spatie/twitter-labs - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [API Development](/categories/api)
4. /
5. spatie/twitter-labs

ActiveLibrary[API Development](/categories/api)

spatie/twitter-labs
===================

PHP client for Twitter Labs endpoints

1.1.0(6y ago)403316MITPHPPHP ^7.4CI failing

Since Apr 28Pushed 3mo ago2 watchersCompare

[ Source](https://github.com/spatie/twitter-labs)[ Packagist](https://packagist.org/packages/spatie/twitter-labs)[ Docs](https://github.com/spatie/twitter-labs)[ GitHub Sponsors](https://github.com/spatie)[ Patreon](https://www.patreon.com/spatie)[ RSS](/packages/spatie-twitter-labs/feed)WikiDiscussions main Synced 2d ago

READMEChangelog (4)Dependencies (8)Versions (5)Used By (0)

PHP client for Twitter Labs endpoints
=====================================

[](#php-client-for-twitter-labs-endpoints)

[![Latest Version on Packagist](https://camo.githubusercontent.com/f64d0ab8e7185dbe0a3fb6af5eb239ee800b86fe7ce93877120a36525d796783/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f7370617469652f747769747465722d6c6162732e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/spatie/twitter-labs)[![GitHub Tests Action Status](https://camo.githubusercontent.com/0c71ca3d31819ede2faf2565198530e6a8ab0ba424be06a0ebbce4cd4a011e2f/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f776f726b666c6f772f7374617475732f7370617469652f747769747465722d6c6162732f72756e2d74657374733f6c6162656c3d7465737473)](https://github.com/spatie/twitter-labs/actions?query=workflow%3Arun-tests+branch%3Amaster)[![Total Downloads](https://camo.githubusercontent.com/bbe45c0adeff519f1ca2c8511064dbd394e82ccb7bcfc0ed7cf2e83202399fe5/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f7370617469652f747769747465722d6c6162732e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/spatie/twitter-labs)

This package aims to implement some of the realtime endpoints exposed by Twitter's new API, as the old realtime Twitter streams are being deprecated.

> Twitter Developer Labs is where you’ll have early access to new API endpoints, features and versions. We’ll use Labs to test out new ideas and invite our developer community to share their feedback to help shape our roadmap.

*(from the Twitter Developer Labs website)*

Under the hood this is using [ReactPHP](https://reactphp.org) for everything async. Even though you can use the package with no knowledge of ReactPHP, it is recommended to familiarize yourself with its [event loop](https://reactphp.org/event-loop/) concept.

If you're currently using our old [twitter-streaming-api package](https://github.com/spatie/twitter-streaming-api), making the switch to this package should be easy.

Support us
----------

[](#support-us)

[![](https://camo.githubusercontent.com/0b410388971e1912eefc0f41623466f332cf15a3dcf8d6a838f92a51d1759890/68747470733a2f2f6769746875622d6164732e73332e65752d63656e7472616c2d312e616d617a6f6e6177732e636f6d2f747769747465722d6c6162732e6a70673f743d31)](https://spatie.be/github-ad-click/twitter-labs)

We invest a lot of resources into creating [best in class open source packages](https://spatie.be/open-source). You can support us by [buying one of our paid products](https://spatie.be/open-source/support-us).

We highly appreciate you sending us a postcard from your hometown, mentioning which of our package(s) you are using. You'll find our address on [our contact page](https://spatie.be/about-us). We publish all received postcards on [our virtual postcard wall](https://spatie.be/open-source/postcards).

Installation
------------

[](#installation)

You can install the package via composer:

```
composer require spatie/twitter-labs
```

Usage
-----

[](#usage)

Currently, only the **filtered stream endpoints** are implemented. We accept PRs for the other features Twitter Labs exposes.

⚠ You'll need a Twitter Developer account with Twitter Dev Labs access enabled and an application that's enrolled in the filtered streams preview. Have a look at .

### Filtered streams overview

[](#filtered-streams-overview)

You can find the Twitter Labs filtered stream API docs [here](https://developer.twitter.com/en/docs/labs/filtered-stream/overview).

Twitter's filtered stream consists of one streaming endpoint that returns tweets in realtime and three endpoints to control what tweets are included in the realtime endpoint:

- `GET /labs/1/tweets/stream/filter` (realtime)
- `POST /labs/1/tweets/stream/filter/rules` (delete)
- `GET /labs/1/tweets/stream/filter/rules`
- `POST /labs/1/tweets/stream/filter/rules` (create)

To use any of these filtered stream endpoints, you'll need a `FilteredStream` instance. Use the `\Spatie\TwitterLabs\FilteredStream\FilteredStreamFactory` to create this instance for you. The factory's `create` method takes your API credentials and optionally and event loop instance.

### Basic usage: listening for Tweets

[](#basic-usage-listening-for-tweets)

```
$filteredStream = \Spatie\TwitterLabs\FilteredStream\FilteredStreamFactory::create('twitter api token', 'twitter api secret');

$filteredStream->addRule(
    new \Spatie\TwitterLabs\FilteredStream\Rule('cat has:media', 'cat photos')
);

$filteredStream
    ->onTweet(fn (Tweet $tweet) => print($tweet->text . PHP_EOL))
    ->start();
```

The event loop will start when calling `start`. All code after this call will not be executed unless something goes wrong and the event loop is stopped.

#### Managing filters/rules

[](#managing-filtersrules)

Filters for realtime streams work slightly different in Twitter Labs compared to the old Twitter API. The main difference being that filter rules are actually stored per API key and are always applied when connecting to the stream. When adding or removing rules, these changes are also applied in realtime to the streaming endpoint without having to reconnect.

The following methods are available to manage filter rules:

```
public function asyncAddRule(\Spatie\TwitterLabs\FilteredStream\Rule $rule): PromiseInterface;
public function asyncAddRules(\Spatie\TwitterLabs\FilteredStream\Rule ...$rules): PromiseInterface;
public function asyncDeleteRules(string ...$ruleIds): PromiseInterface;
public function asyncSetRules(\Spatie\TwitterLabs\FilteredStream\Rule ...$rules): PromiseInterface;
public function asyncGetRules(): PromiseInterface;

public function addRule(\Spatie\TwitterLabs\FilteredStream\Rule $rule): \Spatie\TwitterLabs\FilteredStream\Responses\Rules\AddRulesResponse;
public function addRules(\Spatie\TwitterLabs\FilteredStream\Rule ...$rules): \Spatie\TwitterLabs\FilteredStream\Responses\Rules\AddRulesResponse;
public function deleteRules(string ...$ruleIds): \Spatie\TwitterLabs\FilteredStream\Responses\Rules\DeleteRulesResponse;
public function setRules(\Spatie\TwitterLabs\FilteredStream\Rule ...$rules): \Spatie\TwitterLabs\FilteredStream\Responses\Rules\ListRulesResponse;
public function getRules(): \Spatie\TwitterLabs\FilteredStream\Responses\Rules\ListRulesResponse;
```

You can either use `async` endpoints asynchronously (don't forget to run `$filteredStream->run()` to start the event loop) or use the regular endpoint synchronously.

Basic example that adds a rule:

```
use Spatie\TwitterLabs\FilteredStream\FilteredStreamFactory;
use Spatie\TwitterLabs\FilteredStream\Rule;

FilteredStreamFactory::create('token', 'secret')
    ->addRule(new Rule('@spatie_be', 'mentioning_spatie'));
```

Basic example that adds a rule asynchronously (can be combined with other tasks running in the same event loop):

```
use React\EventLoop\Factory;
use Spatie\TwitterLabs\FilteredStream\FilteredStreamFactory;
use Spatie\TwitterLabs\FilteredStream\Rule;

$loop = Factory::create();

FilteredStreamFactory::create('token', 'secret', $loop)
    ->asyncAddRule(new Rule('@spatie_be', 'mentioning_spatie'));

$loop->run();
```

Example that syncs rules by getting all existing rules, then deleting them and adding the new rules.

```
use React\EventLoop\Factory;
use Spatie\TwitterLabs\FilteredStream\FilteredStreamFactory;
use Spatie\TwitterLabs\FilteredStream\Rule;

$loop = Factory::create();

FilteredStreamFactory::create('token', 'secret', $loop)
    ->asyncSetRules(new Rule('cat photos')); // or use `setRules()` synchronously

$loop->run();
```

#### Listening for tweets

[](#listening-for-tweets)

You can specify a callback to be executed when Twitter hears a tweet that passes your filter rules. The callback will be executed with just one parameter: `\Spatie\TwitterLabs\FilteredStream\Responses\Tweet\Tweet $tweet`. When everything is set-up you can use the `connect()` method to start listening.

```
use React\EventLoop\Factory;
use Spatie\TwitterLabs\FilteredStream\Responses\Tweet\Tweet;
use Spatie\TwitterLabs\FilteredStream\FilteredStreamFactory;

$loop = Factory::create();

FilteredStreamFactory::create('token', 'secret', $loop)
    ->onTweet(fn(Tweet $tweet) => print($tweet->text))
    ->connect();

$loop->run();
```

As a shorthand, `$filteredStream->start()` is also available. It will connect to the realtime endpoint and start the event loop, even when no event loop was given. This is especially nice when you don't need the event loop anywhere else:

```
use Spatie\TwitterLabs\FilteredStream\Responses\Tweet\Tweet;
use Spatie\TwitterLabs\FilteredStream\FilteredStreamFactory;

FilteredStreamFactory::create('token', 'secret')
    ->onTweet(fn(Tweet $tweet) => print($tweet->text))
    ->start();
```

### Testing

[](#testing)

```
composer test
```

### Changelog

[](#changelog)

Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.

Contributing
------------

[](#contributing)

Please see [CONTRIBUTING](https://github.com/spatie/.github/blob/main/CONTRIBUTING.md) for details.

### Security

[](#security)

If you've found a bug regarding security please mail  instead of using the issue tracker.

Credits
-------

[](#credits)

- [Alex Vanderbist](https://github.com/AlexVanderbist)
- [All Contributors](../../contributors)

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

###  Health Score

41

—

FairBetter than 89% of packages

Maintenance54

Moderate activity, may be stable

Popularity25

Limited adoption so far

Community17

Small or concentrated contributor base

Maturity59

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 55.8% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~4 days

Total

4

Last Release

2193d ago

Major Versions

0.0.1 → 1.0.02020-04-30

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/7535935?v=4)[Spatie](/maintainers/spatie)[@spatie](https://github.com/spatie)

---

Top Contributors

[![AlexVanderbist](https://avatars.githubusercontent.com/u/6287961?v=4)](https://github.com/AlexVanderbist "AlexVanderbist (29 commits)")[![freekmurze](https://avatars.githubusercontent.com/u/483853?v=4)](https://github.com/freekmurze "freekmurze (12 commits)")[![AdrianMrn](https://avatars.githubusercontent.com/u/12762044?v=4)](https://github.com/AdrianMrn "AdrianMrn (7 commits)")[![rahul05ranjan](https://avatars.githubusercontent.com/u/11793455?v=4)](https://github.com/rahul05ranjan "rahul05ranjan (2 commits)")[![danieldevine](https://avatars.githubusercontent.com/u/5939939?v=4)](https://github.com/danieldevine "danieldevine (1 commits)")[![nidhichaudhary562](https://avatars.githubusercontent.com/u/52623437?v=4)](https://github.com/nidhichaudhary562 "nidhichaudhary562 (1 commits)")

---

Tags

apiphprealtimetwittertwitter-labsspatietwitter-labs

###  Code Quality

TestsPHPUnit

Code StylePHP CS Fixer

### Embed Badge

![Health badge](/badges/spatie-twitter-labs/health.svg)

```
[![Health](https://phpackages.com/badges/spatie-twitter-labs/health.svg)](https://phpackages.com/packages/spatie-twitter-labs)
```

###  Alternatives

[spatie/laravel-query-builder

Easily build Eloquent queries from API requests

4.4k26.9M220](/packages/spatie-laravel-query-builder)[spatie/laravel-fractal

An easy to use Fractal integration for Laravel applications

1.9k15.1M99](/packages/spatie-laravel-fractal)[spatie/fractalistic

A developer friendly wrapper around Fractal

38715.3M8](/packages/spatie-fractalistic)[spatie/laravel-json-api-paginate

A paginator that plays nice with the JSON API spec

6314.7M46](/packages/spatie-laravel-json-api-paginate)[spatie/laravel-route-attributes

Auto register routes using PHP attributes

879963.2k18](/packages/spatie-laravel-route-attributes)[spatie/dropbox-api

A minimal implementation of Dropbox API v2

3116.0M36](/packages/spatie-dropbox-api)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
