devua/salesteer-php-sdk
devua/salesteer-php-sdk is a lightweight PHP client for the SaleSteer API. It wraps authentication, requests, and response handling in a simple, framework-friendly interface, so Laravel or plain PHP apps can integrate SaleSteer quickly with minimal boilerplate.
Treat devua/salesteer-php-sdk as a thin, low-adoption API wrapper rather than a mature framework package. With 0 stars, 0 dependents, and a single package identity, your first job is to verify what the SDK actually exposes before designing around it.
Install and pin it
composer require devua/salesteer-php-sdk
Pin an exact version in composer.json until you have contract tests. Do not rely on floating ^ constraints for a package with no dependent ecosystem.
Audit the package before writing application code
README.md for auth, base URI, and example calls.composer.json for PHP version, PSR-18/PSR-17 dependencies, and whether it uses Guzzle, Symfony HTTP Client, or a generated OpenAPI client.src/ and find the main entrypoint: likely a client class, resource classes, and exception types.tests/, examples/, and CHANGELOG.md. If absent, assume you are the test suite.Configure credentials outside code
SALESTEER_BASE_URI=https://api.example.salesteer.tld
SALESTEER_API_KEY=your-token
SALESTEER_TIMEOUT=10
// config/services.php
'salesteer' => [
'base_uri' => env('SALESTEER_BASE_URI'),
'api_key' => env('SALESTEER_API_KEY'),
'timeout' => env('SALESTEER_TIMEOUT', 10),
],
Bind the client once
If the package ships a Laravel service provider, publish/use it. Otherwise bind the SDK client as a singleton:
// app/Providers/AppServiceProvider.php
$this->app->singleton(SalesteerClient::class, function () {
return new SalesteerClient(
config('services.salesteer.api_key'),
config('services.salesteer.base_uri'),
// adjust to the actual constructor exposed by src/
);
});
Adjust class and constructor names to what src/ actually provides. Do not assume the README examples are current.
First use case: a read-only sync Start with a low-risk read endpoint, such as listing contacts, companies, or deals. A nightly read-only sync is the best first integration because it exercises authentication, pagination, DTO hydration, error handling, and rate limits without writing bad data into the CRM.
Verify:
The highest-leverage pattern is to isolate the SDK behind your own adapter. The package is small and low-adoption; your application should not depend on its class names throughout controllers and jobs.
Client as singleton, adapter as boundary
interface SalesteerGateway
{
public function contactsUpdatedSince(?string $cursor): ContactPage;
public function upsertContact(ContactData $contact): string;
}
final class SdkSalesteerGateway implements SalesteerGateway
{
public function __construct(private SalesteerClient $client) {}
public function contactsUpdatedSince(?string $cursor): ContactPage
{
// Map SDK response objects into your own DTOs here.
}
}
This lets you swap the SDK, patch around missing features, or replace it with direct HTTP calls without rewriting domain code.
Read sync pattern
updated_at, or last page token.final class SyncSalesteerContacts implements ShouldQueue
{
use InteractsWithQueue, Queueable;
public function __construct(private ?string $cursor = null) {}
public function handle(SalesteerGateway $salesteer, ContactRepository $contacts): void
{
$page = $salesteer->contactsUpdatedSince($this->cursor);
foreach ($page->items() as $contact) {
$contacts->upsertFromSalesteer($contact);
}
if ($page->nextCursor()) {
self::dispatch($page->nextCursor());
}
}
}
Write pattern
Error handling and retries
Map SDK exceptions into your own exception hierarchy:
try {
$salesteer->upsertContact($data);
} catch (SalesteerValidationException $e) {
throw new ContactRejected($e->getMessage(), previous: $e);
} catch (SalesteerRateLimitException $e) {
$this->release($e->retryAfter ?? 60);
} catch (SalesteerException $e) {
report($e);
throw $e;
}
Retry only network failures, 429, and 5xx. Use exponential backoff with jitter. Respect Retry-After when present.
Testing
Inject a mock PSR-18 client or the SDK’s HTTP client if it exposes one. If the SDK does not support injection, wrap it and test your adapter with recorded fixtures. Keep a small contract test suite that runs against a Salesteer sandbox before releases.
Observability
Log method, path, status code, latency, and any request ID returned by the API. Redact Authorization headers and API keys. Log Salesteer record IDs, not full payloads containing PII.
src/ and run one smoke call in a sandbox first. Generated SDKs often have unintuitive resource and method names.psr/http-client-implementation, Composer may install a client you did not expect. Explicitly require your preferred client and configure timeouts.429 responses, and make throttling configurable.curl to separate SDK bugs from API behavior.vendor/. Composer updates will erase vendor patches.How can I help you explore Laravel packages today?