stitch-digital/simpro-php-sdk
A PHP SDK for the Simpro field service management API. Gives Laravel and PHP apps fluent, typed access to jobs, quotes, customers, sites and invoices, handling authentication and HTTP requests so you can integrate Simpro without boilerplate.
Architecture fit
stitch-digital/simpro-php-sdk is a thin, framework-agnostic PHP client for the Simpro REST API, consumed in Laravel as an outbound integration adapter rather than as an application-layer dependency. The correct placement is behind our own repository/gateway interface (SimproGateway contract bound in a service provider), so that SDK-specific types, casing quirks, and transport concerns never leak into domain code or Eloquent models. The package should be treated as replaceable infrastructure: if we are forced to fork or swap it, only one adapter class should change.
This release strengthens that positioning. The 1.1.23 change — reading and requesting LinkedJobID using Simpro's exact casing — is a serialization/hydration fix, not a feature. It confirms that the SDK's value is largely in getting Simpro's idiosyncratic field naming right, which is precisely the work we do not want to hand-roll and re-discover in our own code.
Integration feasibility
Straightforward. Composer-installable, patch-level bump from 1.1.22, no new configuration surface, no new dependencies, no signature changes to the public API. Integration cost is a version constraint bump plus a regression check on any code path that touches linked jobs (quotes → jobs, job → job relationships). Effort is measured in hours, not days.
Technical risk
Low for the upgrade itself; moderate for the underlying pattern.
LinkedJobID from LinkedJobId implies the hydration layer is casing-sensitive throughout. Other fields may be silently null or dropped rather than erroring. Any field we consume should be added to a contract test covering real payload shapes.null values, not exceptions. Downstream logic that treats a missing LinkedJobID as "no linked job" would create duplicate jobs or orphaned records without any error to alert on.Key questions
LinkedJobID anywhere, and was it previously working by accident (Simpro accepting our casing) or silently returning null?1.1.x?Stack fit
Fits a standard Laravel service architecture: package installed via Composer, credentials and base URL exposed through config/simpro.php backed by environment variables (client ID, secret, region-specific base URL, token store). Authentication is OAuth2 client-credentials style, so token acquisition and refresh should be delegated to the SDK's token provider and cached (Redis/database) rather than re-requested per call. The SDK's response objects must be mapped to our own DTOs at the adapter boundary.
Migration path
No migration required — this is a patch. Sequence is:
~1.1.23 in composer.json and lock.1.1.22 → 1.1.23 locally to confirm the change is confined to the quotes/linked-job hydration path.LinkedJobID now populates where it previously did not.If this is a first integration (no prior assessment exists), the same path applies but followed by a feature-flagged read-only sync of quotes and jobs before any write paths are enabled.
Compatibility
PHP version constraints and Laravel support matrix should be verified against composer.json before adopting — the SDK predates current Laravel majors and is not Laravel-specific, so framework version is unlikely to be a blocker. No breaking changes in this release; downgrade to 1.1.22 is a safe rollback if the casing change regresses an existing workaround we built for the old behaviour.
Sequencing
Adopt 1.1.23 before building any new linked-job functionality. Building against 1.1.22 would mean writing our own casing workaround, which this release makes redundant and which would then conflict. Read paths → contract tests → write paths → scheduled sync.
Maintenance
Low ongoing cost. Release cadence is sparse and patch-oriented; expected maintenance is periodic version bumps plus a diff review. The real maintenance obligation is ours: keep a recorded-payload contract test suite so that upstream fixes like this one are validated by evidence rather than assumed.
Support
Community/agency-supported with no SLA. Escalation path is opening a GitHub issue or PR against the vendor repo. For production dependency on Simpro data, we should assume we may need to patch and consume a fork; the adapter boundary keeps that to a composer.json repository entry.
Scaling
Scaling constraints sit with the Simpro API, not the SDK: rate limits, pagination on list endpoints, and per-tenant API budgets. Sync jobs should be queued, chunked, and idempotent, with backoff on 429s. Token caching is mandatory — acquiring a token per request will hit auth limits long before data limits. The SDK itself is stateless and horizontally safe.
Failure modes
null rather than an exception. Mitigate with explicit assertions that required fields are present after hydration, and alert on unexpected nulls for fields we depend on.Ramp-up
Minimal for a developer familiar with Laravel HTTP clients and OAuth2. Expected ramp is under a day to a first successful read call in the sandbox. The non-obvious learning curve is Simpro's domain model and field naming conventions — LinkedJobID being a case in point — so budget time for a written field-mapping reference maintained alongside the adapter, and require that new fields be added there with a matching fixture test.
How can I help you explore Laravel packages today?