shedcloud / partner-api
Official PHP client for the ShedCloud Partner API
Requires
- php: ^8.2
- ext-curl: *
- ext-json: *
Requires (Dev)
- phpunit/phpunit: ^11.5
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-08-30 09:32:56 UTC
README
Official PHP client for the ShedCloud Partner API (/partner/v1/*).
Use this package from PHP 8.2+ to call company-scoped Partner API endpoints with an API key (sc_live_…) or OAuth2 client credentials.
Install
composer require shedcloud/partner-api
Hosts
| Environment | Host |
|---|---|
production (default) |
https://go.shedcloud.com |
sandbox |
https://api.shedcloudtest.com |
Pass environment for sandbox, or baseUrl for a custom/local override.
Quick start
API key (production)
<?php require 'vendor/autoload.php'; use ShedCloud\PartnerApi\Auth; use ShedCloud\PartnerApi\Client; $client = new Client([ 'auth' => new Auth(apiKey: getenv('SHEDCLOUD_API_KEY')), ]); $stock = $client->lotStock->list([ 'limit' => 50, 'purchaseType' => 'Lot Stock', 'sort' => 'price', 'order' => 'asc', ]); echo $stock['total'] . PHP_EOL; $unit = $stock['data'][0]; echo $unit['title'] . PHP_EOL; // Typed public photo galleries (CDN URL arrays; empty when none): // $unit['heroImages'], $unit['frontImages'], $unit['backImages'], // $unit['leftImages'], $unit['rightImages'], $unit['exteriorImages'], // $unit['interiorImages']
Sandbox
$client = new Client([ 'environment' => 'sandbox', 'auth' => new Auth(apiKey: getenv('SHEDCLOUD_API_KEY')), ]);
OAuth2 client credentials
$client = new Client([ 'auth' => new Auth( clientId: getenv('SHEDCLOUD_CLIENT_ID'), clientSecret: getenv('SHEDCLOUD_CLIENT_SECRET'), ), ]); $orders = $client->orders->list([ 'status' => 'Unprocessed', 'limit' => 25, ]);
Create credentials in the ShedCloud portal under Settings → Developer API.
Resources
Each resource maps to a section of the hosted reference.
| Client property | Endpoints |
|---|---|
$client->lotStock |
GET /partner/v1/lot-stock |
$client->stockTemplates |
GET /partner/v1/stock-templates |
$client->leads |
GET/POST/PATCH /partner/v1/leads, status + status-history |
$client->quotes |
GET/POST/PATCH /partner/v1/quotes, convert, line-items |
$client->orders |
GET/POST/PATCH /partner/v1/orders, contract, payments, payment-links |
$client->workOrders |
GET/POST/PATCH /partner/v1/work-orders, status + status-history |
$client->locations |
GET/POST/PATCH /partner/v1/locations |
$client->customers |
GET/POST/PATCH /partner/v1/customers, merge |
$client->products |
GET/POST/PATCH /partner/v1/products, create sizes |
$client->domains |
GET /partner/v1/domains, location domains |
$client->agreements |
GET /partner/v1/agreements, state-legal |
$client->users |
GET/POST/PATCH /partner/v1/users, roles |
$client->payments |
GET /partner/v1/payments (read-only) |
$client->documents |
GET /partner/v1/documents, download |
$client->events |
GET /partner/v1/events, each iterator, redeliver, deliveries |
$client->siteEvents |
POST/GET /partner/v1/site-events (visitor behavioral tracking) |
$client->configuratorSessions |
POST /partner/v1/configurator-sessions |
Idempotency and optimistic concurrency
use ShedCloud\PartnerApi\RequestOptions; $quote = $client->quotes->create([ 'serialNumber' => 'SC-2024-00123', 'customer' => ['name' => 'Jane Doe', 'email' => 'jane@example.com'], ], RequestOptions::withIdempotencyKey(bin2hex(random_bytes(16)))); $client->orders->update($order['id'], [ 'customerPhone' => '555-0100', // Optional Sold-by fields (camelCase on the wire): // 'saleDate' => '2026-07-15', // or null to clear // 'soldPricing' => ['total' => 12500], // partial; null clears all ], RequestOptions::withIfMatch($order['version']));
For boolean query params that must be sent even when false, wrap the value:
use ShedCloud\PartnerApi\QueryValue; $client->quotes->list(['converted' => new QueryValue(false)]);
Webhooks
Verify webhook deliveries with the subscription secret against the raw request body:
use ShedCloud\PartnerApi\Webhooks; $body = file_get_contents('php://input'); Webhooks::verifySignature( getenv('SHEDCLOUD_WEBHOOK_SECRET'), $_SERVER['HTTP_X_SHEDCLOUD_SIGNATURE'] ?? '', $body, ); http_response_code(200);
Errors
Failed responses throw ShedCloud\PartnerApi\Exception\PartnerApiException (or AuthException for OAuth token failures):
use ShedCloud\PartnerApi\Exception\PartnerApiException; try { $client->orders->get($id); } catch (PartnerApiException $e) { echo $e->status, ' ', $e->getMessage(), PHP_EOL; // $e->isUnauthorized(), isForbidden(), isNotFound(), isRateLimited() }
Scopes
use ShedCloud\PartnerApi\Scopes; Scopes::LOT_STOCK_READ; // partner-api.lot-stock.read Scopes::ORDERS_WRITE; // partner-api.orders.write Scopes::SITE_EVENTS_WRITE; // partner-api.site-events.write Scopes::SITE_EVENTS_READ; // partner-api.site-events.read
Development
composer install
composer test
Release
Packagist indexes git tags as versions (not composer.json).
git tag v0.2.0 git push origin main git push origin v0.2.0
With the Packagist GitHub Hook enabled, pushing the tag updates the package automatically. Install:
composer require shedcloud/partner-api:^0.2
Versioning & changelog
The Partner API is additive-only within /partner/v1. This package is tagged with semver in lockstep with API additions.
- API changes: hosted changelog
Docs
- Partner API reference: https://go.shedcloud.com/partner/reference
- Backend source of truth:
shedcloud-api-go/docs/PARTNER_API.md - TypeScript/JavaScript:
@shedcloud/partner-api - Go:
shedcloud-gomod/partnerapi - Python:
shedcloud-partner-api - Ruby:
shedcloud-partner_api