toddstoker / keap-sdk
Keap SDK for accessing Keap's Rest v1 and v2 API endpoints
Installs: 68
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 0
pkg:composer/toddstoker/keap-sdk
Requires
- php: ^8.4
- saloonphp/saloon: ^3.0
Requires (Dev)
- laravel/pint: dev-main
- psy/psysh: @stable
- spatie/ray: ^1.0@dev
- symfony/var-dumper: 8.1.x-dev
This package is auto-updated.
Last update: 2025-12-19 23:04:25 UTC
README
A modern, type-safe PHP SDK for the Keap REST API (v1 & v2), built on SaloonPHP.
Features
- 🔐 Multiple Authentication Methods - OAuth2, Personal Access Tokens, and Service Account Keys
- 🎯 Type-Safe - Full PHP 8.4+ type hints and readonly classes
- 🔄 Dual API Support - Seamlessly work with both v1 and v2 APIs
- 🏭 Resource Factory Pattern - Dynamic, cached resource instantiation
- 📦 SaloonPHP Powered - Built on the robust SaloonPHP HTTP client
- 🎨 Fluent API - Intuitive, chainable method calls
- 📚 Well Documented - Comprehensive PHPDoc and examples
Installation
composer require toddstoker/keap-sdk
Quick Start
use Toddstoker\KeapSdk\Keap; use Toddstoker\KeapSdk\Credentials\PersonalAccessToken; // Initialize the SDK $keap = new Keap(new PersonalAccessToken('your-token-here')); // Get a contact $contact = $keap->contacts()->get(123); echo $contact['given_name'] . ' ' . $contact['family_name']; // List contacts $result = $keap->contacts()->list(limit: 50); foreach ($result['contacts'] as $contactData) { echo $contactData['email_addresses'][0]['email'] ?? 'No email' . "\n"; } // Create a contact $newContact = $keap->contacts()->create([ 'given_name' => 'John', 'family_name' => 'Doe', 'email_addresses' => [ ['email' => 'john@example.com', 'field' => 'EMAIL1'] ] ]); echo "Created contact: {$newContact['id']}";
Authentication
The SDK supports three authentication methods:
1. Personal Access Token (Recommended)
Best for server-to-server integrations. Get your PAT here.
use Toddstoker\KeapSdk\Credentials\PersonalAccessToken; $keap = new Keap(new PersonalAccessToken('your-pat-token'));
2. Service Account Key
For machine-to-machine authentication. Get your SAK here.
use Toddstoker\KeapSdk\Credentials\ServiceAccountKey; $keap = new Keap(new ServiceAccountKey('your-service-key'));
3. OAuth2
For user-based access when building applications. The SDK implements the full OAuth2 authorization code flow.
use Toddstoker\KeapSdk\Credentials\OAuth; // Step 1: Create OAuth credential and connector $oauth = new OAuth( clientId: 'your-client-id', clientSecret: 'your-client-secret', redirectUri: 'https://your-app.com/callback' ); $keap = new Keap($oauth); // Step 2: Generate authorization URL $authorizationUrl = $keap->getAuthorizationUrl(); $state = $keap->getState(); // Store this for verification // Redirect user to $authorizationUrl // User authorizes and is redirected back with code and state // Step 3: Exchange authorization code for access token $authenticator = $keap->getAccessToken( code: $_GET['code'], state: $_GET['state'], expectedState: $storedState ); // Step 4: Authenticate the connector $keap->authenticate($authenticator); // Step 5: Save tokens to your database // Access properties directly (OAuth is readonly) $accessToken = $keap->credential->accessToken; $refreshToken = $keap->credential->refreshToken; $expiresAt = $keap->credential->expiresAt; // saveToDatabase($accessToken, $refreshToken, $expiresAt); // Now you can make API calls $contact = $keap->contacts()->get(123); // Step 6: Restore OAuth session from stored tokens $oauth = new OAuth( clientId: 'your-client-id', clientSecret: 'your-client-secret', redirectUri: 'https://your-app.com/callback', accessToken: $storedAccessToken, refreshToken: $storedRefreshToken, expiresAt: $storedExpiresAt ); $keap = new Keap($oauth); // Step 7: Refresh token when expired if ($oauth->expiresAt < new DateTimeImmutable()) { // Returns a NEW OAuth credential instance with updated tokens $updatedCredential = $keap->refreshToken(); // Important: Save the new tokens (Keap rotates refresh tokens) $newAccessToken = $updatedCredential->accessToken; $newRefreshToken = $updatedCredential->refreshToken; $newExpiresAt = $updatedCredential->expiresAt; // saveToDatabase($newAccessToken, $newRefreshToken, $newExpiresAt); }
API Versions
The SDK supports both v1 and v2 of the Keap REST API, with v2 as the default.
// Use v2 (default, recommended) $keap = new Keap(new PersonalAccessToken('token')); $contact = $keap->contacts()->get(123); // Use v1 for entire session $keapV1 = new Keap(new PersonalAccessToken('token'), apiVersion: 1); // Override version per resource call $contactsV1 = $keap->contacts(1); // Force v1 $contactsV2 = $keap->contacts(2); // Force v2
Available Resources
Contacts
// List contacts $result = $keap->contacts()->list( limit: 100, offset: 0, email: 'john@example.com' ); // Get a contact $contact = $keap->contacts()->get(123); // Create a contact $contact = $keap->contacts()->create([ 'given_name' => 'John', 'family_name' => 'Doe', 'email_addresses' => [ ['email' => 'john@example.com', 'field' => 'EMAIL1'] ] ]); // Update a contact $contact = $keap->contacts()->update(123, [ 'job_title' => 'Developer' ]); // Delete a contact $keap->contacts()->delete(123); // V1 only: Tag management $keap->contacts(1)->applyTag(contactId: 123, tagId: 456); $keap->contacts(1)->removeTag(contactId: 123, tagId: 456);
Architecture
The SDK uses a clean, modern architecture:
- Keap - Main connector class extending SaloonPHP's Connector
- ResourceFactory - Manages dynamic resource instantiation and caching
- Credentials - Encapsulate authentication methods
- Resources - Group related API operations (Contacts, Companies, etc.)
- Requests - Individual API request classes
How It Works
$keap->contacts()->get(123); // 1. PHP's __call() magic method is triggered // 2. ResourceFactory is initialized (if not already) // 3. Factory looks up 'contacts' in the class map // 4. ContactsResource is created/retrieved from cache // 5. get() method is called on the resource // 6. Request is sent via SaloonPHP
Adding New Resources
- Create resource classes in
src/Resources/V1/and/orsrc/Resources/V2/ - Add mapping to
ResourceFactory::$classMap:
'companies' => [ 1 => \Toddstoker\KeapSdk\Resources\V1\CompaniesResource::class, 2 => \Toddstoker\KeapSdk\Resources\V2\CompaniesResource::class, ],
- Resource is now accessible via
$keap->companies()
See examples/adding-resources.php for a detailed guide.
Error Handling
The SDK provides specific exception classes:
use Toddstoker\KeapSdk\Exceptions\{ClientException\NotFoundException,ClientException\TooManyRequestsException,ValidationException}; try { $contact = $keap->contacts()->get(999999); } catch (NotFoundException $e) { echo "Contact not found: " . $e->getMessage(); } catch (TooManyRequestsException $e) { echo "Rate limit exceeded. Retry after: " . $e->retryAfter . " seconds"; } catch (ValidationException $e) { echo "Validation failed: " . $e->getMessage(); print_r($e->errors); }
Examples
Check out the examples/ directory for detailed examples:
authentication.php- All authentication methodsadding-resources.php- How to extend the SDK with new resources
Requirements
- PHP 8.4 or higher
- Composer
- SaloonPHP 3.x
Development
Documentation
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
License
This project is licensed under the MIT License - see the LICENSE file for details.
Support
- Issues: GitHub Issues
- Keap API Support: Keap Developer Portal
Acknowledgments
- Built with SaloonPHP
- Developed with ☕ and Claude Code
Note: This SDK is not officially affiliated with Keap. For official support, please visit the Keap Developer Portal.