unopim / api-php-client
Official PHP API client for the UnoPim PIM — authenticate, paginate, and manage products, categories, attributes, families, channels, locales, and assets. Framework-agnostic, PSR-18 compatible.
Requires
- php: >=8.1
- ext-curl: *
- ext-json: *
- psr/http-client: ^1.0
- psr/http-factory: ^1.0
- psr/http-message: ^1.0|^2.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.0
- pestphp/pest: ^3.0
- phpstan/phpstan: ^1.10
Suggests
- guzzlehttp/guzzle: ^7.0 — popular PSR-18 HTTP client
- guzzlehttp/psr7: ^2.0 — Guzzle PSR-7 implementation
- nyholm/psr7: ^1.0 — lightweight PSR-7 implementation
- symfony/http-client: ^6.0|^7.0 — Symfony PSR-18 HTTP client
This package is auto-updated.
Last update: 2026-04-29 16:23:45 UTC
README
Official PHP client for the UnoPim PIM REST API.
Works in any PHP project — Laravel, Symfony, WordPress, Magento, Drupal, plain PHP.
Install
composer require unopim/api-php-client
That's it. The bundled cURL client works out of the box — no extra HTTP package needed. Want Guzzle or Symfony HttpClient instead? See HTTP clients.
Connect
use Unopim\ApiClient\UnoPimClient; $client = UnoPimClient::create( baseUrl: 'https://your-unopim.example.com', clientId: 'your-client-id', clientSecret: 'your-client-secret', username: 'admin@example.com', password: 'your-admin-password', );
Where do credentials come from? In UnoPim admin: System → API Clients → Create. Note the Client ID & Secret. Username / password = any admin user's login.
Examples
List all products
foreach ($client->products()->iterate() as $product) { echo $product['sku'], PHP_EOL; }
Get one product
$product = $client->products()->get('MY-SKU-001');
Create a product
$client->products()->create([ 'sku' => 'NEW-SKU', 'parent' => null, 'family' => 'default', 'type' => 'simple', 'additional' => null, 'values' => [ 'common' => [ 'sku' => 'NEW-SKU', 'name' => 'My Product', ], 'channel_locale_specific' => [ 'ecommerce' => [ 'en_US' => [ 'description' => '<p>Hello world.</p>', 'price' => '{"USD":"49.99"}', ], ], ], ], ]);
Update a product
$client->products()->update('NEW-SKU', [ 'sku' => 'NEW-SKU', 'family' => 'default', 'type' => 'simple', 'values' => [ 'common' => ['sku' => 'NEW-SKU', 'name' => 'Updated Name'], ], ]);
Delete a product
$client->products()->delete('NEW-SKU');
Categories, attributes, families…
Same shape — $client->categories(), $client->attributes(), $client->attributeFamilies(), etc.
// All categories $categories = $client->categories()->list(); // Create attribute $client->attributes()->create([ 'code' => 'color', 'type' => 'select', 'labels' => ['en_US' => 'Color'], 'is_unique' => false, 'is_required' => false, ]); // Add options to it $client->attributes()->createOptions('color', [ ['code' => 'red', 'labels' => ['en_US' => 'Red']], ['code' => 'blue', 'labels' => ['en_US' => 'Blue']], ]);
Upload a product image
$client->mediaFiles()->uploadProductMedia('/path/to/image.jpg');
Raw call to any endpoint
If a resource isn't wrapped yet:
$client->get('/api/v1/rest/some-endpoint'); $client->post('/api/v1/rest/some-endpoint', $payload); $client->put('/api/v1/rest/some-endpoint/code', $payload); $client->delete('/api/v1/rest/some-endpoint/code'); // Auto-paginates $all = $client->fetchAll('/api/v1/rest/products', batchSize: 100);
More runnable scripts in examples/.
Available resources
| Accessor | Methods |
|---|---|
$client->locales() |
list(), get($code) |
$client->currencies() |
list(), get($code) |
$client->channels() |
list(), get($code) |
$client->categories() |
list(), get($code), create($data), update($code, $data) |
$client->categoryFields() |
list(), get($code), create($data), update($code, $data) |
$client->attributes() |
list(), get($code), create($data), update($code, $data), listOptions($code), createOptions($code, $data), updateOptions($code, $data) |
$client->attributeGroups() |
list(), get($code), create($data), update($code, $data) |
$client->attributeFamilies() |
list(), get($code), create($data), update($code, $data) |
$client->products() |
list(), iterate(), get($sku), create($data), update($sku, $data), delete($sku) |
$client->configurableProducts() |
list(), iterate(), get($sku), create($data), update($sku, $data) |
$client->mediaFiles() |
uploadProductMedia($filePath), uploadCategoryMedia($filePath) |
Errors
use Unopim\ApiClient\Exception\ApiException; use Unopim\ApiClient\Exception\AuthenticationException; try { $client->products()->get('MISSING-SKU'); } catch (AuthenticationException $e) { // 401 — bad credentials } catch (ApiException $e) { $e->getStatusCode(); // int $e->getResponseBody(); // string $e->getMessage(); }
Using other HTTP clients
The bundled cURL adapter works for everyone. If you want Guzzle, Symfony HttpClient, or any other PSR-18 client:
Guzzle
composer require guzzlehttp/guzzle guzzlehttp/psr7
use GuzzleHttp\Client as Guzzle; use GuzzleHttp\Psr7\HttpFactory; use Unopim\ApiClient\UnoPimClient; $g = new Guzzle(['timeout' => 30]); $f = new HttpFactory(); $client = UnoPimClient::createWithHttpClient( 'https://your-unopim.example.com', 'cid', 'csec', 'admin@example.com', 'pass', $g, $f, $f, );
Symfony HttpClient
composer require symfony/http-client nyholm/psr7
use Symfony\Component\HttpClient\Psr18Client; use Unopim\ApiClient\UnoPimClient; $s = new Psr18Client(); $client = UnoPimClient::createWithHttpClient( 'https://your-unopim.example.com', 'cid', 'csec', 'admin@example.com', 'pass', $s, $s, $s, );
Requirements
- PHP 8.1+
ext-curl,ext-json- UnoPim server v2.0+
License
MIT — see LICENSE.
Issues / Contributing
Open an issue or send a PR. See CONTRIBUTING.md.
Maintained by Webkul Software Pvt. Ltd.