Store Hugs Developers

AdminClient

Your ERP, warehouse, CRM or app on a shop's products, stock, orders, customers, marketing, reviews, quotations, keys and webhooks, through the Admin API, from your PHP server.

Get started

  1. Make a key. In the Store Hugs panel, open Shop Settings → Integration API and add an Admin key (sa_live_…). Choose its scopes and, optionally, the IP addresses your servers call from. The key is shown once; keep it in your server's secrets.

  2. Install the SDK:

    composer require storehugs/integration
    
  3. Make a client and a first call:

    use StoreHugs\Integration\AdminClient;
    
    $admin = new AdminClient(getenv('STOREHUGS_ADMIN_KEY'));
    
    $shop = $admin->shop();
    echo $shop['name'], ' ', $shop['plan'], ' ', $shop['currency'];
    
  4. Sync. Read every record changed since your last run, oldest change first, and keep the last updatedAt you saw:

    foreach ($admin->products->all(['updatedSince' => $lastSyncedAt]) as $product) {
        $erp->save($product);
        $lastSyncedAt = $product['updatedAt'] ?? $lastSyncedAt;
    }
    
  5. Write safely. Every write is retried with the same Idempotency-Key (see retries). Pass the updatedAt you read with a change, so a newer edit is never overwritten (409 edit_conflict):

    $product = $admin->products->get(12);
    $admin->products->update(12, ['price' => 19.5], unmodifiedSince: $product['updatedAt']);
    

The key names the shop; there's no shop id to pass.

Constructor

Parameter Type
apiKey string Required. An Admin key, made in the panel or issued to your app.
baseUrl string The panel's origin. Default https://my.storehugs.com (AdminClient::DEFAULT_BASE_URL).
http HttpOptions Timeouts, retries and your own HTTP client (see HTTP options).

Scopes

Each method needs the scope it names. A key without it gets 403 insufficient_scope.

Scope Allows
shop:read The shop's details.
keys:read, keys:write Storefront keys.
products:read, products:write Products.
inventory:write Stock levels.
orders:read, orders:write Orders, their status and shipments.
customers:read, customers:write Customers and wholesale memberships.
marketing:read, marketing:write Coupons and offers.
reviews:read, reviews:write Reviews and the shop's replies.
quotations:read, quotations:write B2B quotations.
webhooks:read, webhooks:write Webhook endpoints.

Lists and sync

Every resource with a list has two methods:

They take these query fields, and the resource's filters below:

Query Type
limit int Records per page, up to 100.
cursor string The page to read, from meta['nextCursor'].
updatedSince string ISO 8601. Only records changed since then, oldest change first.
$query = ['status' => 'processing', 'limit' => 50];

do {
    $page = $admin->orders->list($query);
    // … $page['data']
    $query['cursor'] = $page['meta']['nextCursor'];
} while ($query['cursor'] !== null);

Changes and $unmodifiedSince

Methods that change a record (update, setMembership) take $unmodifiedSince: the record's updatedAt as you read it, as a string or a DateTimeInterface. If the record has changed since, the change is refused with 409 edit_conflict.

Every write takes $idempotencyKey last (see retries). Use named arguments to pass either:

$admin->coupons->update(5, ['value' => 15], unmodifiedSince: $coupon['updatedAt'], idempotencyKey: 'coupon-5-v2');

Models and methods

Each page describes every method in full: its parameters, the fields it sends and gets back, its refusals and an example.