dmstr / php-bc4-client
Modern PHP client for Basecamp 4 (BC3 API) — OAuth 2.0 with refresh-token rotation
0.1.0
2026-06-10 20:08 UTC
Requires
- php: ^8.4
- psr/http-client: ^1.0
- psr/log: ^3.0
- symfony/http-client: ^7.0
- symfony/http-client-contracts: ^3.0
Requires (Dev)
- phpunit/phpunit: ^12.0
- symfony/var-dumper: ^7.0
This package is auto-updated.
Last update: 2026-06-10 20:38:53 UTC
README
php-bc4-client
Modern PHP 8.4 client for the Basecamp 4 API (which is hosted at https://3.basecampapi.com/{account_id}/... and follows the BC3 API specification).
Built on Symfony HttpClient, with a small surface area focused on what real applications need: Projects, Todolists, Todos, People, plus a complete OAuth 2.0 flow including transparent refresh-token rotation.
Features
- OAuth 2.0 web-server flow with Launchpad (
launchpad.37signals.com) - Refresh-token rotation: tokens are rotated on every refresh and persisted via a pluggable
TokenStorageInterface— your application picks the storage backend (Doctrine, Redis, file, in-memory) - Transparent token lifecycle: proactive refresh when
expires_atis near, reactive refresh on401, automatic single retry of the original request - Rate-limit aware: exponential backoff on
429, configurable retry count invalid_grantdetection: throwsInvalidGrantExceptionwhen the refresh token is rejected, signalling that a fresh user-authorization is required- Pagination via
Link: <…>; rel="next"headers, transparent for callers - Resource-oriented API:
$client->projects()->all(),$client->todos()->getInProject($id, $todolistId)etc.
Installation
composer require dmstr/php-bc4-client
Minimum Usage
use Dmstr\Bc4Client\Authentication\OAuth2Authentication; use Dmstr\Bc4Client\Client\Bc4Client; $auth = new OAuth2Authentication( clientId: 'YOUR_CLIENT_ID', clientSecret: 'YOUR_CLIENT_SECRET', appName: 'My App', appContact: 'ops@example.com', storage: $myTokenStorage, // implements TokenStorageInterface ); $client = new Bc4Client(accountId: '6164391', authentication: $auth); foreach ($client->projects()->all() as $project) { echo $project['name'], "\n"; }
Architecture
Authentication/
AuthenticationInterface — minimal request-decoration contract
OAuth2Authentication — Bearer token, refresh lifecycle
TokenStorageInterface — your app implements this
AuthorizationFlow — initial code → tokens, account discovery
Client/
Bc4Client — entrypoint, hands out resources
Exception/
Bc4ApiException — base exception
InvalidGrantException — refresh token rejected
RequestException — wrapped HTTP error
Resource/
AbstractResource — pagination + request helper
ProjectsResource
TodoSetsResource
TodolistsResource
TodosResource
PeopleResource
Inspired by
schmunk42/php-bcx-client— the BC2 (BCX-API) sibling
License
MIT