PHPackages                             spontena/pb-php - 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. spontena/pb-php

ActiveLibrary[API Development](/categories/api)

spontena/pb-php
===============

Pandorabots API client for PHP

v2.1.3(2mo ago)631061MITPHPPHP ^8.1CI passing

Since Nov 13Pushed 2mo ago6 watchersCompare

[ Source](https://github.com/spontena/pb-php)[ Packagist](https://packagist.org/packages/spontena/pb-php)[ RSS](/packages/spontena-pb-php/feed)WikiDiscussions master Synced today

READMEChangelogDependencies (4)Versions (10)Used By (1)

pb-php
======

[](#pb-php)

Pandorabots API client for PHP.

> See the official Pandorabots API documentation:

Requirements
------------

[](#requirements)

- PHP 8.1 or newer
- ext-json
- [Guzzle](https://github.com/guzzle/guzzle) 7.5+

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

[](#installation)

```
composer require spontena/pb-php
```

Quickstart
----------

[](#quickstart)

```
use Spontena\PbPhp\PBClient;
use Spontena\PbPhp\FileKind;
use Spontena\PbPhp\Exception\ApiException;

$pb = new PBClient(
    host:    'https://api.pandorabots.com',
    appId:   getenv('PB_APP_ID'),
    userKey: getenv('PB_USER_KEY'),
);

try {
    $pb->create('mybot');
    $pb->upload(__DIR__ . '/aiml/greetings.aiml', 'mybot');
    $pb->compile('mybot');

    $reply = $pb->talk('hello', 'mybot');
    foreach ($reply->responses as $line) {
        echo $line, "\n";
    }
} catch (ApiException $e) {
    fprintf(STDERR, "Pandorabots API error %d: %s\n", $e->getStatusCode(), $e->getResponseBody());
}
```

A working end-to-end script lives in [`examples/quickstart.php`](examples/quickstart.php). Run it after setting `PB_APP_ID` and `PB_USER_KEY`:

```
PB_APP_ID=xxx PB_USER_KEY=yyy php examples/quickstart.php
```

API reference
-------------

[](#api-reference)

MethodHTTPEndpoint`getBotsList()``GET``/bot/{appId}``create($botname)``PUT``/bot/{appId}/{botname}``delete($botname)``DELETE``/bot/{appId}/{botname}``getBotFiles($botname)``GET``/bot/{appId}/{botname}``getBotFile(FileKind $kind, $botname, ?$name)``GET``/bot/{appId}/{botname}/{kind}[/{name}]` (since v2.1.0)`upload($path, $botname)``PUT``/bot/{appId}/{botname}/{kind}[/{name}]``deleteBotFile($name, FileKind $kind, $botname)``DELETE``/bot/{appId}/{botname}/{kind}[/{name}]``compile($botname)``GET``/bot/{appId}/{botname}/verify``talk($input, $botname, ...)``POST``/talk/{appId}/{botname}``debug($input, $botname, ...)``POST``/talk/{appId}/{botname}` (with `trace` etc.)`atalk($input, ...)``POST``/talk?botkey=...` (botkey auth, bot identified by key)Successful responses are returned as `stdClass` (the decoded JSON body). `getBotsList()` returns a `list` because the API responds with a top-level JSON array. `getBotFile()` returns the raw response body as a `string` (no JSON decoding) — useful for downloading AIML/set/map content. HTTP 4xx/5xx responses raise `Spontena\PbPhp\Exception\ApiException`; bad inputs raise `InvalidArgumentException` or `InvalidFileException`.

`upload()` infers the file kind from the extension:

Extension`FileKind`URL form`.aiml``File``/bot/.../file/{name}``.set``Set``/bot/.../set/{name}``.map``Map``/bot/.../map/{name}``.substitution``Substitution``/bot/.../substitution/{name}``.pdefaults``Pdefaults``/bot/.../pdefaults``.properties``Properties``/bot/.../properties`Migration from v1
-----------------

[](#migration-from-v1)

v2 is a breaking-change release. Notable differences:

- **Namespace** is now `Spontena\PbPhp` (was `spontena\pbphp`); autoloading switched from PSR-0 to PSR-4.
- Constructor accepts named arguments and an optional `botKey` for `atalk()`.
- HTTP errors throw `ApiException` instead of returning `{ status: "error", ... }`.
- `deleteBotFile()` now takes a `FileKind` enum instead of a string.
- `botname` and filenames are URL-encoded.
- `debug()`'s broken `client_name` parameter (the long-standing `$clientname` typo) is fixed.
- Requires PHP 8.1+ and Guzzle 7.5+.

Testing
-------

[](#testing)

### Unit tests (no API access)

[](#unit-tests-no-api-access)

```
composer install
composer test          # PHPUnit unit suite (mocked HTTP, runs by default)
composer analyse       # PHPStan (level 6)
```

CI runs the unit suite on PHP 8.1 / 8.2 / 8.3 / 8.4 — see `.github/workflows/ci.yml`.

### Integration tests (real Pandorabots API)

[](#integration-tests-real-pandorabots-api)

The `tests/Integration/` suite hits the live API to validate that endpoint URLs, request formats, and response shapes still match. It is **not** run by default. Provide credentials via env vars and invoke the `integration` suite explicitly:

```
PB_APP_ID=xxx PB_USER_KEY=yyy vendor/bin/phpunit --testsuite integration
```

Test bots are created with names like `pbphpci` (lowercase alphanumeric only — Pandorabots rejects hyphens) and removed in `tearDown()` even if a test fails.

To exercise `atalk()`, additionally set `PB_BOT_KEY` for an existing, compiled bot whose bot key has been issued in the Pandorabots dashboard:

```
PB_BOT_KEY=zzz \
PB_APP_ID=xxx PB_USER_KEY=yyy \
vendor/bin/phpunit --testsuite integration
```

The bot is identified by the bot key alone — no botname is needed in the request path.

Env varPurpose`PB_APP_ID`Pandorabots app id (required)`PB_USER_KEY`Pandorabots user key (required)`PB_HOST`API host, defaults to `https://api.pandorabots.com``PB_BOT_KEY`Bot key for `atalk()` integration test (optional)License
-------

[](#license)

MIT — see [`LICENSE.txt`](LICENSE.txt).

###  Health Score

54

—

FairBetter than 96% of packages

Maintenance88

Actively maintained with recent releases

Popularity20

Limited adoption so far

Community17

Small or concentrated contributor base

Maturity78

Established project with proven stability

 Bus Factor1

Top contributor holds 85.7% 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 ~524 days

Recently: every ~0 days

Total

9

Last Release

61d ago

Major Versions

1.0.61 → v2.x-dev2026-05-02

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/35491752?v=4)[Keisuke Nakamura](/maintainers/knlab)[@knlab](https://github.com/knlab)

---

Top Contributors

[![knlab](https://avatars.githubusercontent.com/u/35491752?v=4)](https://github.com/knlab "knlab (6 commits)")[![keisuke-nakamura-spontena](https://avatars.githubusercontent.com/u/8910883?v=4)](https://github.com/keisuke-nakamura-spontena "keisuke-nakamura-spontena (1 commits)")

---

Tags

phppandorabotsaimlspontena

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Type Coverage Yes

### Embed Badge

![Health badge](/badges/spontena-pb-php/health.svg)

```
[![Health](https://phpackages.com/badges/spontena-pb-php/health.svg)](https://phpackages.com/packages/spontena-pb-php)
```

###  Alternatives

[tencentcloud/tencentcloud-sdk-php

TencentCloudApi php sdk

3741.3M46](/packages/tencentcloud-tencentcloud-sdk-php)[resend/resend-php

Resend PHP library.

617.2M43](/packages/resend-resend-php)[checkout/checkout-sdk-php

Checkout.com SDK for PHP

563.6M13](/packages/checkout-checkout-sdk-php)[eslazarev/wildberries-sdk

Wildberries OpenAPI clients (generated).

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

Files.com PHP SDK

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

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

1943.1k5](/packages/aimeos-prisma)

PHPackages © 2026

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