PHPackages                             notwonderful/xenforo-sdk - 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. notwonderful/xenforo-sdk

ActiveLibrary[API Development](/categories/api)

notwonderful/xenforo-sdk
========================

PHP SDK for the XenForo REST API

1.0.1(3mo ago)0181MITPHPPHP ^8.3CI passing

Since Mar 6Pushed 3mo agoCompare

[ Source](https://github.com/notwonderful/xenforo-sdk)[ Packagist](https://packagist.org/packages/notwonderful/xenforo-sdk)[ RSS](/packages/notwonderful-xenforo-sdk/feed)WikiDiscussions main Synced 3w ago

READMEChangelog (2)Dependencies (3)Versions (3)Used By (0)

XenForo SDK
===========

[](#xenforo-sdk)

[![PHP 8.3+](https://camo.githubusercontent.com/cb4691349e165573a741c7c5c326f3e21575f3ca8cd79f6fe11cf313573248a7/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7068702d382e332532422d3838393242462e737667)](https://www.php.net/)[![Downloads](https://camo.githubusercontent.com/3a1ee1f51b511b905b006639ef7fe3ed747615dc6e471a9fde62b4c4a458a781/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6e6f74776f6e64657266756c2f78656e666f726f2d73646b2e737667)](https://packagist.org/packages/notwonderful/xenforo-sdk)[![License](https://camo.githubusercontent.com/5df35cc87b382bc3df6cc71dfca7962ec08e1ccd287bb4c3df2389d35ddcf830/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f6e6f74776f6e64657266756c2f78656e666f726f2d73646b2e737667)](https://packagist.org/packages/notwonderful/xenforo-sdk)

PHP SDK for the XenForo REST API.

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

[](#installation)

```
composer require notwonderful/xenforo-sdk
```

Usage
-----

[](#usage)

### Client setup

[](#client-setup)

```
use Notwonderful\XenforoSdk\XenForoClient;

$xenforo = new XenForoClient(
    baseUrl: 'https://your-forum.com',
    apiKey: 'your-super-user-api-key',
    apiUser: 1, // optional: act as specific user (super user key required)
);
```

### Available APIs

[](#available-apis)

MethodAPI ClassDescription`$xenforo->alerts()`AlertsUser alerts`$xenforo->attachments()`AttachmentsFile attachments`$xenforo->auth()`AuthLogin, session lookup, login tokens`$xenforo->conversations()`ConversationsPrivate conversations &amp; messages`$xenforo->featuredContent()`FeaturedContentFeatured content`$xenforo->forums()`ForumsForum info &amp; thread listings`$xenforo->index()`IndexSite &amp; API info`$xenforo->me()`MeCurrent user profile`$xenforo->nodes()`NodesNode tree management`$xenforo->oauth()`OAuthOAuth2 token management`$xenforo->posts()`PostsThread replies`$xenforo->profilePosts()`ProfilePostsProfile posts &amp; comments`$xenforo->search()`SearchSearch operations`$xenforo->searchForums()`SearchForumsSearch forum nodes`$xenforo->stats()`StatsSite statistics`$xenforo->threads()`ThreadsThread CRUD &amp; moderation`$xenforo->users()`UsersUser CRUD &amp; avatars### Auth

[](#auth)

All auth endpoints require a **super user API key**.

```
// Validate login credentials
$user = $xenforo->auth()->login('username', 'password');

// Lookup user from session or remember cookie
$user = $xenforo->auth()->fromSession(sessionId: 'xf_session_value');
$user = $xenforo->auth()->fromSession(rememberCookie: 'xf_user_cookie');

// Generate auto-login token
$token = $xenforo->auth()->loginToken(
    userId: 1,
    remember: true,
    returnUrl: 'https://your-site.com/dashboard',
);
// $token->loginUrl, $token->loginToken, $token->expiryDate
```

### OAuth2

[](#oauth2)

```
use Notwonderful\XenforoSdk\Enum\GrantType;
use Notwonderful\XenforoSdk\Enum\TokenTypeHint;

// Exchange authorization code for token
$result = $xenforo->oauth()->token(
    grantType: GrantType::AuthorizationCode,
    clientId: 'your-client-id',
    clientSecret: 'your-client-secret',
    code: 'authorization-code',
    redirectUri: 'https://your-app.com/callback',
);

// Refresh an expired token
$result = $xenforo->oauth()->token(
    grantType: GrantType::RefreshToken,
    clientId: 'your-client-id',
    refreshToken: 'your-refresh-token',
);

// Revoke a token
$xenforo->oauth()->revokeToken('token-to-revoke');
$xenforo->oauth()->revokeToken('token', TokenTypeHint::AccessToken);
```

### Users

[](#users)

```
// List users (paginated, alphabetically)
$result = $xenforo->users()->list(page: 1);

// Create a user
$user = $xenforo->users()->create(
    username: 'johndoe',
    password: 's3cret',
    email: 'john@example.com',
    extra: ['custom_title' => 'New Member'],
);

// Find users by email (admin only) or name prefix
$result = $xenforo->users()->findByEmail('john@example.com');
$result = $xenforo->users()->findByName('joh');

// Get / Update / Delete a user
$user = $xenforo->users()->find(42);
$user = $xenforo->users()->update(42, ['custom_title' => 'Senior Member']);
$xenforo->users()->destroy(42, renameTo: 'Former Member');

// Avatar management
$xenforo->users()->uploadAvatar(42, '/path/to/avatar.png');
$xenforo->users()->deleteAvatar(42);

// Profile posts
$result = $xenforo->users()->profilePosts(42, page: 1);
```

### Me (Current User)

[](#me-current-user)

```
// Get current user info
$user = $xenforo->me()->find();

// Update profile
$xenforo->me()->update(['custom_title' => 'VIP', 'profile[location]' => 'NYC']);

// Change email / password
$xenforo->me()->updateEmail('current-password', 'new@email.com');
$xenforo->me()->updatePassword('current-password', 'new-password');

// Avatar
$xenforo->me()->uploadAvatar('/path/to/avatar.png');
$xenforo->me()->deleteAvatar();
```

### Threads

[](#threads)

```
// List threads with filters
$result = $xenforo->threads()->list(
    page: 1,
    order: 'last_post_date',
    direction: 'desc',
    lastDays: 7,
);

// Create a thread
$thread = $xenforo->threads()->create(
    nodeId: 5,
    title: 'Hello World',
    message: 'This is my first thread!',
    extra: ['prefix_id' => 1, 'sticky' => true],
);

// Get / Update / Delete
$thread = $xenforo->threads()->find(42, withPosts: true, page: 1);
$thread = $xenforo->threads()->update(42, ['title' => 'Updated Title', 'sticky' => false]);
$xenforo->threads()->destroy(42, reason: 'spam');

// Move thread to another forum
$xenforo->threads()->move(42, targetNodeId: 10, starterAlert: true);

// Vote / Feature
$xenforo->threads()->vote(42, 'up');
$xenforo->threads()->feature(42, ['title' => 'Custom feature title']);
$xenforo->threads()->unfeature(42);

// Get posts in thread
$result = $xenforo->threads()->posts(42, page: 2);
```

### Posts

[](#posts)

```
// Reply to a thread
$post = $xenforo->posts()->create(threadId: 42, message: 'My reply');

// Get / Update / Delete
$post = $xenforo->posts()->find(100);
$post = $xenforo->posts()->update(100, ['message' => 'Edited message', 'silent' => true]);
$xenforo->posts()->destroy(100, hardDelete: true, reason: 'spam');

// React / Vote / Mark as solution
$xenforo->posts()->react(100, 1);
$xenforo->posts()->vote(100, 'up');
$xenforo->posts()->markSolution(100);
```

### Forums

[](#forums)

```
// Get forum info
$forum = $xenforo->forums()->find(5);
// $forum->nodeId, $forum->title, $forum->discussionCount, $forum->messageCount

// Get forum (threads are available via $forum->raw['threads'] when requested)
$forum = $xenforo->forums()->find(5, withThreads: true, page: 1, order: 'post_date');

// Get threads from forum
$result = $xenforo->forums()->threads(5, page: 1, unread: true);

// Mark forum as read
$xenforo->forums()->markRead(5);
```

### Nodes

[](#nodes)

```
// Get node tree / flattened
$result = $xenforo->nodes()->list();
$result = $xenforo->nodes()->flattened();

// CRUD
$node = $xenforo->nodes()->create(['node[title]' => 'New Forum', 'node[parent_node_id]' => 0, 'node_type_id' => 'Forum']);
$node = $xenforo->nodes()->find(5);
$node = $xenforo->nodes()->update(5, ['node[title]' => 'Renamed']);
$xenforo->nodes()->destroy(5, deleteChildren: true);
```

### Conversations

[](#conversations)

```
// List conversations
$result = $xenforo->conversations()->list(page: 1, unread: true);

// Create a conversation
$convo = $xenforo->conversations()->create(
    recipientIds: [2, 3],
    title: 'Hello!',
    message: 'How are you?',
);

// Get / Update
$convo = $xenforo->conversations()->find(10, withMessages: true, page: 1);
$convo = $xenforo->conversations()->update(10, title: 'New Title');

// Reply to conversation
$msg = $xenforo->conversations()->reply(conversationId: 10, message: 'Thanks!');

// Management
$xenforo->conversations()->invite(10, [4, 5]);
$xenforo->conversations()->star(10, star: true);
$xenforo->conversations()->markRead(10);
$xenforo->conversations()->markUnread(10);
$xenforo->conversations()->labels(10, ['important', 'work']);
$xenforo->conversations()->destroy(10, ignore: true);

// Message operations
$msg = $xenforo->conversations()->findMessage(50);
$msg = $xenforo->conversations()->updateMessage(50, message: 'Edited');
$xenforo->conversations()->reactToMessage(50, 1);
```

### Alerts

[](#alerts)

```
// List alerts
$result = $xenforo->alerts()->list(page: 1, unread: true);

// Get alert
$alert = $xenforo->alerts()->find(42);
// $alert->contentType, $alert->action, $alert->alertText, $alert->viewUrl

// Send alert (super user key only)
$xenforo->alerts()->send(toUserId: 5, alert: 'You have a new reward!', linkUrl: '/rewards');

// Mark alerts
$xenforo->alerts()->markAll(read: true);
$xenforo->alerts()->mark(42, read: true);
```

### Attachments

[](#attachments)

```
// Create attachment key and upload
$result = $xenforo->attachments()->newKey('post', ['thread_id' => '42']);
$key = $result['key'];

$result = $xenforo->attachments()->upload($key, '/path/to/file.png');

// Get / List / Delete
$attachment = $xenforo->attachments()->find(10);
$result = $xenforo->attachments()->list($key);
$xenforo->attachments()->destroy(10);
```

### Profile Posts

[](#profile-posts)

```
// Create profile post
$post = $xenforo->profilePosts()->create(userId: 5, message: 'Hello!');

// Get / Update
$post = $xenforo->profilePosts()->find(10, withComments: true, direction: 'asc');
$post = $xenforo->profilePosts()->update(10, ['message' => 'Edited']);

// Comments
$result = $xenforo->profilePosts()->comments(10, page: 1);
$comment = $xenforo->profilePosts()->createComment(profilePostId: 10, message: 'Nice post!');
$comment = $xenforo->profilePosts()->findComment(5);
$comment = $xenforo->profilePosts()->updateComment(5, ['message' => 'Edited']);

// React
$xenforo->profilePosts()->react(10, 1);
$xenforo->profilePosts()->reactToComment(5, 1);

// Delete
$xenforo->profilePosts()->destroy(10, hardDelete: true);
$xenforo->profilePosts()->destroyComment(5);
```

### Featured Content

[](#featured-content)

```
$result = $xenforo->featuredContent()->list(page: 1, contentType: 'thread', userId: 5);
```

### Search

[](#search)

```
// Create a search
$result = $xenforo->search()->create(['keywords' => 'hello world', 'search_type' => 'post']);

// Search a specific member's content
$result = $xenforo->search()->member(['user_id' => 42]);

// Get / Load older results
$result = $xenforo->search()->find(searchId: 15);
$result = $xenforo->search()->older(searchId: 15);
```

### Search Forums

[](#search-forums)

```
$result = $xenforo->searchForums()->find(5, withThreads: true);
$result = $xenforo->searchForums()->threads(5, page: 2);
```

### Index

[](#index)

```
$result = $xenforo->index()->info();
// $result['version_id'], $result['site_title'], $result['base_url'], $result['api_url']
```

### Stats

[](#stats)

```
$result = $xenforo->stats()->all();
```

### Error handling

[](#error-handling)

```
use Notwonderful\XenforoSdk\Exception\ApiException;

try {
    $xenforo->auth()->login('admin', 'wrong-password');
} catch (ApiException $e) {
    $e->getMessage();  // "Incorrect password."
    $e->statusCode;    // 400
    $e->errors;        // [{code, message, params}, ...]
}
```

### Custom HTTP client

[](#custom-http-client)

You can inject your own Guzzle instance for proxies, timeouts, logging, etc.:

```
use GuzzleHttp\Client;

$http = new Client([
    'base_uri' => 'https://your-forum.com/api/',
    'headers'  => ['XF-Api-Key' => 'your-key'],
    'timeout'  => 10,
]);

$xenforo = new XenForoClient('https://your-forum.com', 'your-key', http: $http);
```

Testing
-------

[](#testing)

```
composer test
```

###  Health Score

40

—

FairBetter than 86% of packages

Maintenance79

Regular maintenance activity

Popularity15

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity50

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% 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 ~0 days

Total

2

Last Release

112d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/d8d32e96910a3e8d0794abc7ca155b2299f0fb046145221a9e1733dfe19c181d?d=identicon)[notwonderful](/maintainers/notwonderful)

---

Top Contributors

[![notwonderful](https://avatars.githubusercontent.com/u/102656911?v=4)](https://github.com/notwonderful "notwonderful (14 commits)")

---

Tags

api-clientoauth2php-sdkxenforoxenforo-2xenforo2

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Type Coverage Yes

### Embed Badge

![Health badge](/badges/notwonderful-xenforo-sdk/health.svg)

```
[![Health](https://phpackages.com/badges/notwonderful-xenforo-sdk/health.svg)](https://phpackages.com/packages/notwonderful-xenforo-sdk)
```

###  Alternatives

[tencentcloud/tencentcloud-sdk-php

TencentCloudApi php sdk

3661.2M46](/packages/tencentcloud-tencentcloud-sdk-php)[neuron-core/neuron-ai

The PHP Agentic Framework.

2.0k496.1k33](/packages/neuron-core-neuron-ai)[avalara/avataxclient

Client library for Avalara's AvaTax suite of business tax calculation and processing services. Uses the REST v2 API.

528.3M7](/packages/avalara-avataxclient)[eslazarev/wildberries-sdk

Wildberries OpenAPI clients (generated).

252.5k](/packages/eslazarev-wildberries-sdk)[files.com/files-php-sdk

Files.com PHP SDK

2478.1k](/packages/filescom-files-php-sdk)[aimeos/prisma

A powerful PHP package for integrating media related Large Language Models (LLMs) into your applications

1772.4k4](/packages/aimeos-prisma)

PHPackages © 2026

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