Use the TwexAPI PHP SDK to search tweets, scrape Twitter followers, and read X profiles, timelines, replies, and threads. Send DMs, search communities, fetch lists, articles, hashtags, cashtags, and global trending tweets with typed request objects. Like, retweet, follow, and post through documented REST routes. It is a Twitter API alternative for Composer apps and agents.
REST API | TypeScript SDK | Python SDK | Ruby SDK | Java SDK | Kotlin SDK | C# SDK | Dashboard
Speakeasy generates this SDK.
| Task | REST Route | PHP client |
|---|---|---|
| Search tweets without the X API | POST /twitter/advanced_search/page |
$sdk->search->advanced(...) |
| Search hashtags or cashtags | POST /twitter/hashtags, POST /twitter/cashtags |
$sdk->search->hashtags(), $sdk->search->cashtags() |
| Read an X profile | GET /twitter/{screen_name}/about |
$sdk->users->getAbout(...) |
| Read a profile timeline | GET /twitter/{screen_name}/timeline/page |
$sdk->timelines->userPage(...) |
| Scrape Twitter followers | POST /v3/twitter/users/followers |
$sdk->users->followers->list(...) |
| Scrape following accounts | POST /v3/twitter/users/following |
$sdk->users->following->list(...) |
| Read tweet replies | POST /twitter/tweets/{tweet_id}/replies/page |
$sdk->tweets->replies->page(...) |
| Read a tweet thread | POST /twitter/tweets/thread_by_id |
$sdk->tweets->thread(...) |
| Send or read DMs | /v3/twitter/send-dm, /v3/twitter/dm-history |
$sdk->dm |
| Search communities | POST /twitter/community/search |
$sdk->communities->search(...) |
| Get global trending tweets | GET /twitter/global-trending/tweets |
$sdk->trending->tweets(...) |
| Post or reply | POST /twitter/tweets/create |
$sdk->tweets->actions->create(...) |
- Package:
twexapi/x-api-scraper - Source: twexapi-dev/x-api-scraper-php
- Docs: docs.twexapi.io
- License: MIT
- Dashboard: twexapi.io/dashboard
X API Scraper: Speakeasy-ready OpenAPI document for the x-api-scraper TypeScript SDK.
The SDK wraps TwexAPI's X/Twitter API surface with bearer-token authentication. Cookie/proxy based endpoints are excluded except tweet actions, follow/unfollow, and v3 DM operations. Paid engagement services, profile mutation, legacy-only operations, and non-v3 follower/following endpoints remain excluded.
Not affiliated with X Corp.
composer require twexapi/x-api-scraper:^0.1.0Packagist is not published yet. Install from GitHub until it is:
{
"repositories": [
{
"type": "vcs",
"url": "https://github.com/twexapi-dev/x-api-scraper-php.git"
}
],
"require": {
"twexapi/x-api-scraper": "0.1.0"
}
}Then run:
composer updatedeclare(strict_types=1);
require 'vendor/autoload.php';
use XapiScraper\XapiScraper;
use XapiScraper\Models\Components;
$sdk = XapiScraper::builder()
->setSecurity(getenv('X_API_SCRAPER_KEY'))
->build();
$request = new Components\AdvancedSearchCursorQuery(
searchTerms: ['from:elonmusk'],
sortBy: 'Latest',
nextCursor: '',
);
$response = $sdk->search->advanced(request: $request);
var_dump($response);Get an API key from the TwexAPI dashboard. Pass it to setSecurity(), or set X_API_SCRAPER_KEY.
Write actions (tweet, follow, like, DM send) also need a Twitter cookie or auth_token on the request. Pass them on the operation input.
Keep API keys out of source code, URLs, and logs.
This SDK supports the following security scheme globally:
| Name | Type | Scheme |
|---|---|---|
bearerAuth |
http | HTTP Bearer |
To authenticate with the API the bearerAuth parameter must be set when initializing the SDK. For example:
declare(strict_types=1);
require 'vendor/autoload.php';
use XapiScraper;
use XapiScraper\Models\Components;
$sdk = XapiScraper\XapiScraper::builder()
->setSecurity(
'<YOUR_BEARER_TOKEN_HERE>'
)
->build();
$request = new Components\AdvancedSearchCursorQuery(
searchTerms: [
'<value 1>',
'<value 2>',
'<value 3>',
],
sortBy: '<value>',
nextCursor: '',
);
$response = $sdk->search->advanced(
request: $request
);
if ($response->advancedSearchCursorResponse !== null) {
// handle response
}Available methods
- balance - Get Balance
- sentiment - Sentiment Analysis
- members - Get Community Members
- membersPage - Get Community Members by Page
- tweets - Get Community Tweets
- tweetsPage - Get Community Tweets by Page
- search - Search Community
- get - Get Community
- searchTweets - Search Community Tweets
- status - Check DM Permissions
- send - Send DM
- history - Get DM History
- media - Get DM Media
- conversations - Get Conversations
- tweets - Get List Tweets
- tweetsPage - Get List Tweets by Page
- subscribers - Get List Subscribers
- members - Get List Members
- membersPage - Get List Members by Page
- search - Search List
- tweetsAndReplies - Get All Tweets and Replies by User
- userPage - Get User Timeline by Page
- user - Get User Timeline and Fill Count
- tweetsAndRepliesPage - Get All Tweets and Replies by User by Page
- countries - List Global Trend Countries
- topics - List Global Trend Topics
- contents - List Global Trend Content Tags
- tweets - Get Global Trending Tweets
- byCountry - Get Trending Topics
- detail - Get Tweet Detail
- thread - Get Tweet Thread by ID
- lookup - Batch Get Tweets by ID
- similar - Get Similar Tweets
- like - Like a Tweet
- unlike - Unlike a Tweet
- retweet - Retweet a Tweet
- unretweet - Delete Retweet
- createThread - Create a Tweet Thread
- create - Create a Tweet or Reply
- quote - Create a Quote Tweet
- createWithoutCookie - Post Tweet (Auto Cookie)
- bookmark - Bookmark a Tweet
- unbookmark - Delete Bookmark
- deleteBatch - Delete One or More Tweets
- retweeters - Get Retweeters
- retweetersPage - Get Retweeters by Page
- quotes - Get Quote Tweets
- quotesPage - Get Quote Tweets by Page
- page - Get Replies by Page
- getByUsernames - Get Multiple Users by Usernames
- getByIds - Users Details by ID
- verifyAccount - Verify Account Status
- getStatuses - Batch Get User account status
- search - Search User
- follow - Follow User
- unfollow - Unfollow User
- getAccountBased - Get Twitter Account Based in
- getAbout - Get Twitter User About by Screen Name
- list - Get Following (v3)
Some of the endpoints in this SDK support retries. If you use the SDK without any configuration, it will fall back to the default retry strategy provided by the API. However, the default retry strategy can be overridden on a per-operation basis, or across the entire SDK.
To change the default retry strategy for a single API call, simply provide an Options object built with a RetryConfig object to the call:
declare(strict_types=1);
require 'vendor/autoload.php';
use XapiScraper;
use XapiScraper\Models\Components;
use XapiScraper\Utils\Retry;
$sdk = XapiScraper\XapiScraper::builder()
->setSecurity(
'<YOUR_BEARER_TOKEN_HERE>'
)
->build();
$request = new Components\AdvancedSearchCursorQuery(
searchTerms: [
'<value 1>',
'<value 2>',
'<value 3>',
],
sortBy: '<value>',
nextCursor: '',
);
$response = $sdk->search->advanced(
request: $request,
options: Utils\Options->builder()->setRetryConfig(
new Retry\RetryConfigBackoff(
initialInterval: 1,
maxInterval: 50,
exponent: 1.1,
maxElapsedTime: 100,
retryConnectionErrors: false,
))->build()
);
if ($response->advancedSearchCursorResponse !== null) {
// handle response
}If you'd like to override the default retry strategy for all operations that support retries, you can pass a RetryConfig object to the SDKBuilder->setRetryConfig function when initializing the SDK:
declare(strict_types=1);
require 'vendor/autoload.php';
use XapiScraper;
use XapiScraper\Models\Components;
use XapiScraper\Utils\Retry;
$sdk = XapiScraper\XapiScraper::builder()
->setRetryConfig(
new Retry\RetryConfigBackoff(
initialInterval: 1,
maxInterval: 50,
exponent: 1.1,
maxElapsedTime: 100,
retryConnectionErrors: false,
)
)
->setSecurity(
'<YOUR_BEARER_TOKEN_HERE>'
)
->build();
$request = new Components\AdvancedSearchCursorQuery(
searchTerms: [
'<value 1>',
'<value 2>',
'<value 3>',
],
sortBy: '<value>',
nextCursor: '',
);
$response = $sdk->search->advanced(
request: $request
);
if ($response->advancedSearchCursorResponse !== null) {
// handle response
}Handling errors in this SDK should largely match your expectations. All operations return a response object or throw an exception.
By default an API error will raise a Errors\APIException exception, which has the following properties:
| Property | Type | Description |
|---|---|---|
$message |
string | The error message |
$statusCode |
int | The HTTP status code |
$rawResponse |
?\Psr\Http\Message\ResponseInterface | The raw HTTP response |
$body |
string | The response content |
When custom error responses are specified for an operation, the SDK may also throw their associated exception. You can refer to respective Errors tables in SDK docs for more details on possible exception types for each operation. For example, the advanced method throws the following exceptions:
| Error Type | Status Code | Content Type |
|---|---|---|
| Errors\HTTPValidationError | 422 | application/json |
| Errors\APIException | 4XX, 5XX | */* |
declare(strict_types=1);
require 'vendor/autoload.php';
use XapiScraper;
use XapiScraper\Models\Components;
use XapiScraper\Models\Errors;
$sdk = XapiScraper\XapiScraper::builder()
->setSecurity(
'<YOUR_BEARER_TOKEN_HERE>'
)
->build();
try {
$request = new Components\AdvancedSearchCursorQuery(
searchTerms: [
'<value 1>',
'<value 2>',
'<value 3>',
],
sortBy: '<value>',
nextCursor: '',
);
$response = $sdk->search->advanced(
request: $request
);
if ($response->advancedSearchCursorResponse !== null) {
// handle response
}
} catch (Errors\HTTPValidationErrorThrowable $e) {
// handle $e->$container data
throw $e;
} catch (Errors\APIException $e) {
// handle default exception
throw $e;
}You can override the default server globally using the setServer(string $serverName) builder method when initializing the SDK client instance. The selected server will then be used as the default on the operations that use it. This table lists the names associated with the available servers:
| Name | Server | Description |
|---|---|---|
production |
https://api.twexapi.io |
TwexAPI production API |
declare(strict_types=1);
require 'vendor/autoload.php';
use XapiScraper;
use XapiScraper\Models\Components;
$sdk = XapiScraper\XapiScraper::builder()
->setServer('production')
->setSecurity(
'<YOUR_BEARER_TOKEN_HERE>'
)
->build();
$request = new Components\AdvancedSearchCursorQuery(
searchTerms: [
'<value 1>',
'<value 2>',
'<value 3>',
],
sortBy: '<value>',
nextCursor: '',
);
$response = $sdk->search->advanced(
request: $request
);
if ($response->advancedSearchCursorResponse !== null) {
// handle response
}The default server can also be overridden globally using the setServerUrl(string $serverUrl) builder method when initializing the SDK client instance. For example:
declare(strict_types=1);
require 'vendor/autoload.php';
use XapiScraper;
use XapiScraper\Models\Components;
$sdk = XapiScraper\XapiScraper::builder()
->setServerURL('https://api.twexapi.io')
->setSecurity(
'<YOUR_BEARER_TOKEN_HERE>'
)
->build();
$request = new Components\AdvancedSearchCursorQuery(
searchTerms: [
'<value 1>',
'<value 2>',
'<value 3>',
],
sortBy: '<value>',
nextCursor: '',
);
$response = $sdk->search->advanced(
request: $request
);
if ($response->advancedSearchCursorResponse !== null) {
// handle response
}This SDK is in beta, and there may be breaking changes between versions without a major version update. Therefore, we recommend pinning usage to a specific package version. This way, you can install the same version each time without breaking changes unless you are intentionally looking for the latest version.
While we value open-source contributions to this SDK, this library is generated programmatically. Any manual changes added to internal files will be overwritten on the next generation. We look forward to hearing your feedback. Feel free to open a PR or an issue with a proof of concept and we'll do our best to include it in a future release.