intercom/intercom-php
Intercom PHP SDK for PHP 8.1+ that makes it easy to call Intercom APIs. Instantiate IntercomClient with your token, use typed request objects, handle IntercomApiException for 4xx/5xx errors, and iterate list endpoints with automatic pagination via Pager.
Installation:
composer require intercom/intercom-php
Requires PHP 8.1+.
First Use Case: Initialize the client with your Intercom API token and call an endpoint (e.g., create a contact):
use Intercom\IntercomClient;
use Intercom\Contacts\Requests\CreateContactRequest;
$client = new IntercomClient(token: 'YOUR_INTERCOM_TOKEN');
$response = $client->contacts->create(
new CreateContactRequest([
'email' => 'user@example.com',
'name' => 'John Doe',
])
);
Where to Look First:
IntercomClient class: Entry point for all API interactions.Requests/ namespace: Predefined request classes for each endpoint (e.g., CreateContactRequest).CRUD Operations:
Use request classes (e.g., CreateContactRequest, UpdateCompanyRequest) for type safety and validation:
// Create
$client->contacts->create(new CreateContactRequest($data));
// Read (single)
$contact = $client->contacts->get('123');
// Read (paginated)
foreach ($client->contacts->list(['limit' => 50]) as $contact) {
// Process each contact
}
// Update
$client->contacts->update('123', new UpdateContactRequest($data));
// Delete (soft/hard)
$client->contacts->archive('123'); // Soft delete
$client->contacts->delete('123'); // Hard delete (v3.2.0+)
Pagination:
Leverage the Pager interface for automatic pagination:
$pager = $client->companies->list(['limit' => 100]);
foreach ($pager as $company) {
// Process each company
}
// Or iterate pages manually:
foreach ($pager->getPages() as $page) {
foreach ($page->getItems() as $item) {
// Handle items
}
}
Error Handling:
Catch IntercomApiException for API errors and IntercomException for SDK issues:
try {
$client->contacts->create(...);
} catch (IntercomApiException $e) {
logError($e->getMessage(), $e->getCode(), $e->getBody());
}
Legacy Migration:
Use the Legacy namespace alongside the new SDK during transition:
use Intercom\Legacy\IntercomClient as LegacyClient;
$legacyClient = new LegacyClient('token');
Dependency Injection (Laravel):
Bind the client in AppServiceProvider:
public function register()
{
$this->app->singleton(IntercomClient::class, function ($app) {
return new IntercomClient(token: config('services.intercom.token'));
});
}
Inject via constructor:
public function __construct(private IntercomClient $intercom) {}
Custom HTTP Client: Override Guzzle defaults (e.g., timeouts, middleware):
$client = new IntercomClient(options: [
'client' => new \GuzzleHttp\Client([
'timeout' => 10.0,
'headers' => ['User-Agent' => 'MyApp/1.0'],
]),
]);
Rate Limiting: Check headers for limits:
$response = $client->contacts->list([]);
$rateLimit = $response->getRateLimit(); // Returns RateLimit object
API Versioning:
Use baseUrl option for non-default endpoints (e.g., unstable APIs):
$client = new IntercomClient(token: 'token', options: [
'baseUrl' => 'https://api.intercom.io/unstable',
]);
Token Security:
.env or a secrets manager.str_replace).Pagination Edge Cases:
OutOfBoundsException. Validate $pager->isEmpty() before iteration.limit to avoid hitting API rate limits.Legacy Breaking Changes:
php-http/guzzle7-adapter).Timeouts and Retries:
$client->contacts->create(..., options: ['timeout' => 5.0]);
maxRetries: 0.Soft vs. Hard Deletes:
archive() (soft delete) is reversible via API. delete() (hard delete) is permanent (v3.2.0+).Enable Guzzle Debugging: Add middleware to log requests/responses:
$handlerStack = \GuzzleHttp\HandlerStack::create();
$handlerStack->push(\GuzzleHttp\Middleware::tap(function ($request, $options) {
\Log::debug('Intercom Request:', [
'url' => (string) $request->getUri(),
'method' => $request->getMethod(),
'headers' => $request->getHeaders(),
]);
}));
$client = new IntercomClient(options: ['client' => new \GuzzleHttp\Client(['handler' => $handlerStack])]);
Common HTTP Errors:
contacts/{id} vs. companies/{id}).Type Safety:
CreateContactRequest fields).Request::validate() if extending the SDK.Custom Requests: Extend the SDK by creating new request classes (e.g., for undocumented endpoints):
namespace App\Intercom\Requests;
use Intercom\Requests\Request;
class CustomRequest extends Request {
public function __construct(array $data) {
parent::__construct('POST', '/custom-endpoint', $data);
}
}
Register in IntercomClient via setRequestFactory.
Middleware: Add request/response processing:
$handlerStack = \GuzzleHttp\HandlerStack::create();
$handlerStack->push(\GuzzleHttp\Middleware::mapRequest(function ($request) {
$request = $request->withHeader('X-Custom-Header', 'value');
return $request;
}));
Testing: Mock the client for unit tests:
$mockClient = $this->createMock(\Psr\Http\Client\ClientInterface);
$client = new IntercomClient(options: ['client' => $mockClient]);
Queue Jobs: Offload Intercom API calls to queues to avoid timeouts:
use Illuminate\Bus\Queueable;
use Intercom\IntercomClient;
class SyncContactJob implements Queueable {
public function handle(IntercomClient $intercom) {
$intercom->contacts->create(...);
}
}
Service Container:
Override defaults in config/services.php:
'intercom' => [
'token' => env('INTERCOM_TOKEN'),
'timeout' => env('INTERCOM_TIMEOUT', 30),
],
Then inject via constructor with type-hinting.
Events: Trigger Laravel events after Intercom operations:
event(new ContactSynced($contactData));
How can I help you explore Laravel packages today?