Search by

shedcloud / partner-api

ulisescarreon

Official PHP client for the ShedCloud Partner API

v0.5.0 2026-07-30 09:23 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.

Docs