PHPackages                             dimer47/simplemdm-php-sdk - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [API Development](/categories/api)
4. /
5. dimer47/simplemdm-php-sdk

ActiveLibrary[API Development](/categories/api)

dimer47/simplemdm-php-sdk
=========================

PHP SDK for the SimpleMDM API - Manage Apple devices programmatically

00PHP

Since Feb 15Pushed 4mo agoCompare

[ Source](https://github.com/dimer47/simplemdm-php-sdk)[ Packagist](https://packagist.org/packages/dimer47/simplemdm-php-sdk)[ RSS](/packages/dimer47-simplemdm-php-sdk/feed)WikiDiscussions main Synced today

READMEChangelogDependenciesVersions (1)Used By (0)

📱 SimpleMDM PHP SDK
===================

[](#-simplemdm-php-sdk)

[![PHP](https://camo.githubusercontent.com/f300b22ba00aa3a0ef67aaab5765489aef8759bc5cdb9af55c0526a00fd80962/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e312532422d3737374242343f7374796c653d666c61742d737175617265266c6f676f3d706870266c6f676f436f6c6f723d7768697465)](https://camo.githubusercontent.com/f300b22ba00aa3a0ef67aaab5765489aef8759bc5cdb9af55c0526a00fd80962/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e312532422d3737374242343f7374796c653d666c61742d737175617265266c6f676f3d706870266c6f676f436f6c6f723d7768697465) [![Guzzle](https://camo.githubusercontent.com/c9f3fc56c6f7c0d03c0bbfacd9d47b58337a5bc33471091c27ce2d369e824ff6/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f47757a7a6c652d372e302532422d6f72616e67653f7374796c653d666c61742d737175617265)](https://camo.githubusercontent.com/c9f3fc56c6f7c0d03c0bbfacd9d47b58337a5bc33471091c27ce2d369e824ff6/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f47757a7a6c652d372e302532422d6f72616e67653f7374796c653d666c61742d737175617265) [![Laravel](https://camo.githubusercontent.com/2cb4e02cb1a57f0d3773ae54c997215d1e8f0df9671acab2added04cfce64022/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c61726176656c2d636f6d70617469626c652d4646324432303f7374796c653d666c61742d737175617265266c6f676f3d6c61726176656c266c6f676f436f6c6f723d7768697465)](https://camo.githubusercontent.com/2cb4e02cb1a57f0d3773ae54c997215d1e8f0df9671acab2added04cfce64022/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c61726176656c2d636f6d70617469626c652d4646324432303f7374796c653d666c61742d737175617265266c6f676f3d6c61726176656c266c6f676f436f6c6f723d7768697465) [![License](https://camo.githubusercontent.com/152aa2a37725b9fd554b28ff24d270f6071c67927a63e6d635a55c8e188e20c7/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d677265656e3f7374796c653d666c61742d737175617265)](https://camo.githubusercontent.com/152aa2a37725b9fd554b28ff24d270f6071c67927a63e6d635a55c8e188e20c7/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d677265656e3f7374796c653d666c61742d737175617265) [![Tests](https://camo.githubusercontent.com/3001ebe3288ee788487aae1473d1311b1d6ace6108065bd9d21df97bad13a841/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f54657374732d3230302532307061737365642d627269676874677265656e3f7374796c653d666c61742d737175617265)](https://camo.githubusercontent.com/3001ebe3288ee788487aae1473d1311b1d6ace6108065bd9d21df97bad13a841/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f54657374732d3230302532307061737365642d627269676874677265656e3f7374796c653d666c61742d737175617265) [![Beta](https://camo.githubusercontent.com/dd98045b074bda60c35f2afd1210125401713d4f0e1a6ecec42289914020e689/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5374617475732d426574612d79656c6c6f773f7374796c653d666c61742d737175617265)](https://camo.githubusercontent.com/dd98045b074bda60c35f2afd1210125401713d4f0e1a6ecec42289914020e689/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5374617475732d426574612d79656c6c6f773f7374796c653d666c61742d737175617265)

> ⚠️ **This SDK is in beta.** It has not been extensively tested in production environments. Unit and integration tests are included in the source code and can be run with your own API key and SimpleMDM environment. **Use in production at your own risk.**

A PHP SDK for the [SimpleMDM API](https://api.simplemdm.com/v1) to programmatically manage Apple devices. Compatible with Laravel and any PHP 8.1+ project. 🍎

🎉 Features
----------

[](#-features)

- 📱 **Full device management** — CRUD, lock, wipe, restart, bluetooth, lost mode, etc.
- 📦 **20 API resources** covering the entire SimpleMDM v1 API
- 🔄 **Automatic rate limiting** — smart retry on 429 errors
- 🧩 **Laravel ready** — Service provider, facade and dependency injection
- ⚡ **Async-friendly** — Guzzle HTTP under the hood
- 🧪 **200 tests** (unit + integration) with VCR cassettes

📍 Installation
--------------

[](#-installation)

```
composer require dimer47/simplemdm-php-sdk
```

🚀 Quick Start
-------------

[](#-quick-start)

```
use SimpleMDM\SimpleMDM;

$mdm = new SimpleMDM('your-api-key');

// List all devices
$devices = $mdm->devices->list();

// Get a specific device
$device = $mdm->devices->get(123);

// Lock a device
$mdm->devices->lock(123, [
    'message' => 'This device has been locked.',
    'phone_number' => '555-0123',
]);
```

🔧 Laravel Integration
---------------------

[](#-laravel-integration)

### ⚙️ Configuration

[](#️-configuration)

The package auto-discovers the service provider and facade. Publish the config file:

```
php artisan vendor:publish --tag=simplemdm-config
```

Add your API key to `.env`:

```
SIMPLEMDM_API_KEY=your-api-key

```

### 🏷️ Usage with Facade

[](#️-usage-with-facade)

```
use SimpleMDM\Laravel\Facades\SimpleMDM;

$devices = SimpleMDM::devices->list();
$account = SimpleMDM::account->get();
```

### 💉 Usage with Dependency Injection

[](#-usage-with-dependency-injection)

```
use SimpleMDM\SimpleMDM;

class DeviceController extends Controller
{
    public function index(SimpleMDM $mdm)
    {
        return $mdm->devices->list();
    }
}
```

📚 Available Resources
---------------------

[](#-available-resources)

### 🏢 Account

[](#-account)

```
$mdm->account->get();
$mdm->account->update(['name' => 'My Company']);
```

### 📱 Devices

[](#-devices)

```
$mdm->devices->list();
$mdm->devices->get($id);
$mdm->devices->create('Device Name', $groupId);
$mdm->devices->update($id, ['name' => 'New Name']);
$mdm->devices->delete($id);

// Actions
$mdm->devices->lock($id, ['message' => '...', 'phone_number' => '...']);
$mdm->devices->wipe($id);
$mdm->devices->restart($id);
$mdm->devices->shutdown($id);
$mdm->devices->refresh($id);
$mdm->devices->pushApps($id);
$mdm->devices->clearPasscode($id);
$mdm->devices->clearFirmwarePassword($id);
$mdm->devices->clearRestrictionsPassword($id);
$mdm->devices->updateOS($id);

// Firmware & Recovery passwords
$mdm->devices->rotateFirmwarePassword($id);
$mdm->devices->clearRecoveryLockPassword($id);
$mdm->devices->rotateRecoveryLockPassword($id);
$mdm->devices->rotateFileVaultKey($id);

// Admin password
$mdm->devices->setAdminPassword($id, ['password' => '...']);
$mdm->devices->rotateAdminPassword($id);

// Bluetooth & Remote Desktop
$mdm->devices->enableBluetooth($id);
$mdm->devices->disableBluetooth($id);
$mdm->devices->enableRemoteDesktop($id);
$mdm->devices->disableRemoteDesktop($id);

// Related data
$mdm->devices->listInstalledApps($id);
$mdm->devices->listProfiles($id);
$mdm->devices->listUsers($id);
$mdm->devices->deleteUser($deviceId, $userId);

// Custom attributes
$mdm->devices->listCustomAttributes($id);
$mdm->devices->setCustomAttribute($id, 'attribute_name', 'value');
$mdm->devices->setCustomAttributes($id, ['attr1' => 'val1', 'attr2' => 'val2']); // bulk

// Other
$mdm->devices->setTimeZone($id, 'Europe/Paris');
$mdm->devices->unenroll($id);
```

### 📦 Apps

[](#-apps)

```
$mdm->apps->list();
$mdm->apps->get($id);
$mdm->apps->create('/path/to/app.ipa', 'App Name');           // Upload binary
$mdm->apps->createFromAppStore('899247664', 'App Name');       // From App Store ID
$mdm->apps->createFromBundleId('com.example.app', 'App Name'); // From Bundle ID
$mdm->apps->update($id, ['name' => 'Updated Name']);
$mdm->apps->delete($id);

// Munki
$mdm->apps->uploadMunkiPkgInfo($id, '/path/to/pkginfo.plist');
$mdm->apps->deleteMunkiPkgInfo($id);
```

### 📋 Assignment Groups

[](#-assignment-groups)

```
$mdm->assignmentGroups->list();
$mdm->assignmentGroups->get($id);
$mdm->assignmentGroups->create('Group Name');
$mdm->assignmentGroups->update($id, ['name' => 'New Name']);
$mdm->assignmentGroups->delete($id);

// Apps
$mdm->assignmentGroups->assignApp($groupId, $appId);
$mdm->assignmentGroups->unassignApp($groupId, $appId);
$mdm->assignmentGroups->pushApps($id);
$mdm->assignmentGroups->updateApps($id);

// Devices
$mdm->assignmentGroups->assignDevice($groupId, $deviceId);
$mdm->assignmentGroups->unassignDevice($groupId, $deviceId);

// Device Groups
$mdm->assignmentGroups->assignDeviceGroup($groupId, $deviceGroupId);
$mdm->assignmentGroups->unassignDeviceGroup($groupId, $deviceGroupId);

// Profiles
$mdm->assignmentGroups->assignProfile($groupId, $profileId);
$mdm->assignmentGroups->unassignProfile($groupId, $profileId);
$mdm->assignmentGroups->syncProfiles($id);

// Other
$mdm->assignmentGroups->clone($id);
$mdm->assignmentGroups->getCustomAttributes($id);
$mdm->assignmentGroups->setCustomAttribute($id, 'attr_name', 'value');
```

### 🏷️ Custom Attributes

[](#️-custom-attributes)

```
$mdm->customAttributes->list();
$mdm->customAttributes->get($id);
$mdm->customAttributes->create('Attribute Name', 'default_value');
$mdm->customAttributes->update($id, ['name' => 'New Name']);
$mdm->customAttributes->delete($id);
```

### 📄 Custom Configuration Profiles

[](#-custom-configuration-profiles)

```
$mdm->customConfigurationProfiles->list();
$mdm->customConfigurationProfiles->get($id);
$mdm->customConfigurationProfiles->create('/path/to/profile.mobileconfig');
$mdm->customConfigurationProfiles->update($id, ['name' => 'New Name']);
$mdm->customConfigurationProfiles->delete($id);
$mdm->customConfigurationProfiles->download($id);

// Per-device assignment
$mdm->customConfigurationProfiles->pushToDevice($profileId, $deviceId);
$mdm->customConfigurationProfiles->removeFromDevice($profileId, $deviceId);

// Device group assignment
$mdm->customConfigurationProfiles->assignToDeviceGroup($profileId, $deviceGroupId);
$mdm->customConfigurationProfiles->unassignFromDeviceGroup($profileId, $deviceGroupId);
```

### 📜 Custom Declarations (DDM)

[](#-custom-declarations-ddm)

```
$mdm->customDeclarations->list();
$mdm->customDeclarations->get($id);
$mdm->customDeclarations->create('com.apple.configuration.management.test', '/path/to/payload.json', 'Declaration Name');
$mdm->customDeclarations->update($id, ['name' => 'New Name']);
$mdm->customDeclarations->delete($id);
$mdm->customDeclarations->download($id);

// Per-device
$mdm->customDeclarations->pushToDevice($declarationId, $deviceId);
$mdm->customDeclarations->removeFromDevice($declarationId, $deviceId);
```

### 🔗 DEP Servers

[](#-dep-servers)

```
$mdm->depServers->list();
$mdm->depServers->get($id);
$mdm->depServers->listDevices($id);
$mdm->depServers->getDevice($serverId, $depDeviceId);
$mdm->depServers->sync($id);
```

### 📧 Enrollments

[](#-enrollments)

```
$mdm->enrollments->list();
$mdm->enrollments->get($id);
$mdm->enrollments->delete($id);
$mdm->enrollments->sendInvitation($id, 'user@example.com');
```

### 📲 Installed Apps

[](#-installed-apps)

```
$mdm->installedApps->get($id);
$mdm->installedApps->update($id);
$mdm->installedApps->delete($id);
```

### 📝 Logs

[](#-logs)

```
$mdm->logs->list(['namespace' => 'device']);
$mdm->logs->get($id);
```

### 📍 Lost Mode

[](#-lost-mode)

```
$mdm->lostMode->enable($deviceId, [
    'message' => 'Please return this device.',
    'phone_number' => '555-0123',
]);
$mdm->lostMode->disable($deviceId);
$mdm->lostMode->playSound($deviceId);
$mdm->lostMode->updateLocation($deviceId);
```

### ⚙️ Managed App Configs

[](#️-managed-app-configs)

```
$mdm->managedAppConfigs->list($appId);
$mdm->managedAppConfigs->create($appId, 'config_key', 'config_value', 'string');
$mdm->managedAppConfigs->push($appId);
$mdm->managedAppConfigs->delete($appId, $configId);
$mdm->managedAppConfigs->deleteAll($appId);
```

### 🛡️ Profiles

[](#️-profiles)

```
$mdm->profiles->list();
$mdm->profiles->get($id);
$mdm->profiles->assignToDevice($profileId, $deviceId);
$mdm->profiles->unassignFromDevice($profileId, $deviceId);
$mdm->profiles->assignToDeviceGroup($profileId, $deviceGroupId);
$mdm->profiles->unassignFromDeviceGroup($profileId, $deviceGroupId);
```

### 🔐 Push Certificate

[](#-push-certificate)

```
$mdm->pushCertificate->get();
$mdm->pushCertificate->update('/path/to/cert.pem', 'apple-id@example.com');
$mdm->pushCertificate->getSignedCsr();
```

### 📜 Scripts

[](#-scripts)

```
$mdm->scripts->list();
$mdm->scripts->get($id);
$mdm->scripts->create('Script Name', '/path/to/script.sh', variableSupport: true);
$mdm->scripts->update($id, ['name' => 'New Name']);
$mdm->scripts->delete($id);
```

### ▶️ Script Jobs

[](#️-script-jobs)

```
$mdm->scriptJobs->list();
$mdm->scriptJobs->get($id);
$mdm->scriptJobs->create($scriptId, [
    'device_ids' => [1, 2, 3],
    'assignment_group_ids' => [10],
]);
$mdm->scriptJobs->cancel($id);
```

❌ Error Handling
----------------

[](#-error-handling)

```
use SimpleMDM\Exceptions\ApiException;
use SimpleMDM\Exceptions\AuthenticationException;
use SimpleMDM\Exceptions\RateLimitException;

try {
    $devices = $mdm->devices->list();
} catch (AuthenticationException $e) {
    // Invalid API key (401)
} catch (RateLimitException $e) {
    // Too many requests (429)
    $retryAfter = $e->getRetryAfter(); // seconds until rate limit resets
} catch (ApiException $e) {
    // Other API error
    $statusCode = $e->getStatusCode();
    $responseBody = $e->getResponseBody();
}
```

🧪 Testing
---------

[](#-testing)

```
# Unit tests only
vendor/bin/pest tests/Unit/

# Full suite (unit + integration)
vendor/bin/pest

# With Docker
docker compose run --rm php vendor/bin/pest
```

Integration tests use a **VCR cassette system** that records real API responses and replays them. To record new cassettes, set `SIMPLEMDM_API_KEY` in `.env` and delete the corresponding cassette in `tests/Fixtures/cassettes/`.

### 📊 API Coverage

[](#-api-coverage)

> 🧪 **200 tests** | ✅ **404 assertions** | ⏭️ **17 skipped**

Tests were run against the real SimpleMDM API with a supervised iPad (iOS 12.5).

ResourceMethodEndpointUnitIntegration**🏢 Account**`get()``GET /account`✅✅`update()``PATCH /account`✅✅**📦 Apps**`list()``GET /apps`✅✅`get()``GET /apps/{id}`✅✅`create()``POST /apps` (binary)✅🔶`createFromAppStore()``POST /apps` (App Store)✅✅`createFromBundleId()``POST /apps` (Bundle ID)✅🔶`update()``PATCH /apps/{id}`✅🔶`delete()``DELETE /apps/{id}`✅✅`listInstalls()``GET /apps/{id}/installs`✅✅`uploadMunkiPkgInfo()``POST .../munki_pkginfo`✅🔶`deleteMunkiPkgInfo()``DELETE .../munki_pkginfo`✅🔶**📋 Assignment Groups**`list()``GET /assignment_groups`✅✅`get()``GET /assignment_groups/{id}`✅✅`create()``POST /assignment_groups`✅✅`update()``PATCH /assignment_groups/{id}`✅✅`delete()``DELETE /assignment_groups/{id}`✅✅`assignApp()``POST .../apps/{appId}`✅✅`unassignApp()``DELETE .../apps/{appId}`✅✅`assignDevice()``POST .../devices/{deviceId}`✅✅`unassignDevice()``DELETE .../devices/{deviceId}`✅✅`assignDeviceGroup()``POST .../device_groups/{id}`✅⏭️`unassignDeviceGroup()``DELETE .../device_groups/{id}`✅⏭️`pushApps()``POST .../push_apps`✅✅`updateApps()``POST .../update_apps`✅✅`syncProfiles()``POST .../sync_profiles`✅⏭️`clone()``POST .../clone`✅✅`assignProfile()``POST .../profiles/{id}`✅⏭️`unassignProfile()``DELETE .../profiles/{id}`✅⏭️`getCustomAttributes()``GET .../custom_attribute_values`✅✅`setCustomAttribute()``PUT .../custom_attribute_values/{n}`✅✅**🏷️ Custom Attributes**`list()``GET /custom_attributes`✅✅`get()``GET /custom_attributes/{id}`✅✅`create()``POST /custom_attributes`✅✅`update()``PATCH /custom_attributes/{id}`✅✅`delete()``DELETE /custom_attributes/{id}`✅✅**📄 Custom Config Profiles**`list()``GET /custom_configuration_profiles`✅✅`create()``POST /custom_configuration_profiles`✅✅`update()``PATCH .../{id}`✅✅`delete()``DELETE .../{id}`✅✅`download()``GET .../download`✅✅`pushToDevice()``POST .../devices/{deviceId}`✅✅`removeFromDevice()``DELETE .../devices/{deviceId}`✅✅`assignToDeviceGroup()``POST .../device_groups/{id}`✅🔶`unassignFromDeviceGroup()``DELETE .../device_groups/{id}`✅🔶**📜 Custom Declarations**`list()``GET /custom_declarations`✅✅`create()``POST /custom_declarations`✅✅`update()``PATCH /custom_declarations/{id}`✅✅`delete()``DELETE /custom_declarations/{id}`✅✅`download()``GET .../download`✅✅`pushToDevice()``POST .../devices/{deviceId}`✅⏭️ iOS 15+`removeFromDevice()``DELETE .../devices/{deviceId}`✅⏭️ iOS 15+**🔗 DEP Servers**`list()``GET /dep_servers`✅✅`get()``GET /dep_servers/{id}`✅⏭️`listDevices()``GET .../dep_devices`✅⏭️`getDevice()``GET .../dep_devices/{id}`✅⏭️`sync()``POST .../sync`✅⏭️**📱 Device Groups**`list()``GET /device_groups`✅✅`get()``GET /device_groups/{id}`✅⏭️`assignDevice()``POST .../devices/{deviceId}`✅⏭️`clone()``POST .../clone`✅⏭️`getCustomAttributes()``GET .../custom_attribute_values`✅🔶`setCustomAttribute()``PUT .../custom_attribute_values/{n}`✅🔶**📱 Devices**`list()``GET /devices`✅✅`get()``GET /devices/{id}`✅✅`create()``POST /devices`✅✅`update()``PATCH /devices/{id}`✅✅`delete()``DELETE /devices/{id}`✅✅`listInstalledApps()``GET .../installed_apps`✅✅`listProfiles()``GET .../profiles`✅✅`listUsers()``GET .../users`✅✅`listCustomAttributes()``GET .../custom_attribute_values`✅✅`setCustomAttribute()``PUT .../custom_attribute_values/{n}`✅✅`setCustomAttributes()``PUT .../custom_attribute_values`✅✅`refresh()``POST .../refresh`✅✅`lock()``POST .../lock`✅✅`clearPasscode()``POST .../clear_passcode`✅✅`clearRestrictionsPassword()``POST .../clear_restrictions_password`✅✅`updateOS()``POST .../update_os`✅✅`restart()``POST .../restart`✅✅`shutdown()``POST .../shutdown`✅✅`pushApps()``POST .../push_apps`✅✅`setTimeZone()``POST .../set_time_zone`✅✅`enableBluetooth()``POST .../bluetooth`✅✅`disableBluetooth()``DELETE .../bluetooth`✅✅`wipe()``POST .../wipe`✅⛔`unenroll()``POST .../unenroll`✅⛔`deleteUser()``DELETE .../users/{userId}`✅🔶`enableRemoteDesktop()``POST .../remote_desktop`✅🖥️`disableRemoteDesktop()``DELETE .../remote_desktop`✅🖥️`rotateFirmwarePassword()``POST .../rotate_firmware_password`✅🖥️`clearFirmwarePassword()``POST .../clear_firmware_password`✅🖥️`clearRecoveryLockPassword()``POST .../clear_recovery_lock_password`✅🖥️`rotateRecoveryLockPassword()``POST .../rotate_recovery_lock_password`✅🖥️`rotateFileVaultKey()``POST .../rotate_filevault_key`✅🖥️`setAdminPassword()``POST .../set_admin_password`✅🖥️`rotateAdminPassword()``POST .../rotate_admin_password`✅🖥️**📧 Enrollments**`list()``GET /enrollments`✅✅`get()``GET /enrollments/{id}`✅✅`delete()``DELETE /enrollments/{id}`✅✅`sendInvitation()``POST .../invitations`✅✅**📲 Installed Apps**`get()``GET /installed_apps/{id}`✅⏭️`update()``POST .../update`✅🔶`delete()``DELETE /installed_apps/{id}`✅🔶**📝 Logs**`list()``GET /logs`✅✅`get()``GET /logs/{id}`✅✅**📍 Lost Mode**`enable()``POST .../lost_mode`✅✅`disable()``DELETE .../lost_mode`✅✅`playSound()``POST .../play_sound`✅✅`updateLocation()``POST .../update_location`✅✅**⚙️ Managed App Configs**`list()``GET /apps/{id}/managed_configs`✅✅`create()``POST .../managed_configs`✅✅`push()``POST .../managed_configs/push`✅✅`delete()``DELETE .../managed_configs/{id}`✅✅**🛡️ Profiles**`list()``GET /profiles`✅✅`get()``GET /profiles/{id}`✅⏭️`assignToDevice()``POST .../devices/{deviceId}`✅⏭️`unassignFromDevice()``DELETE .../devices/{deviceId}`✅⏭️`assignToDeviceGroup()``POST .../device_groups/{id}`✅⏭️`unassignFromDeviceGroup()``DELETE .../device_groups/{id}`✅⏭️**🔐 Push Certificate**`get()``GET /push_certificate`✅✅`update()``PUT /push_certificate`✅⛔`getSignedCsr()``GET .../scsr`✅✅**📜 Scripts**`list()``GET /scripts`✅✅`get()``GET /scripts/{id}`✅✅`create()``POST /scripts`✅✅`update()``PATCH /scripts/{id}`✅✅`delete()``DELETE /scripts/{id}`✅✅**▶️ Script Jobs**`list()``GET /script_jobs`✅✅`get()``GET /script_jobs/{id}`✅⏭️`create()``POST /script_jobs`✅⏭️ 🖥️`cancel()``DELETE /script_jobs/{id}`✅⏭️ 🖥️#### 🔑 Legend

[](#-legend)

IconMeaning✅**Tested and validated** against the real SimpleMDM API⏭️**Skipped** — resource not available in the test environment or missing prerequisites🔶**Not integration tested** — covered by unit tests only (HTTP mocks)🖥️**macOS only** — requires an enrolled macOS device, unit tested only⛔**Intentionally not tested** — destructive/irreversible action (wipe, unenroll, push certificate)### ⚠️ Limitations and Warnings

[](#️-limitations-and-warnings)

> 🔴 **This SDK is in beta.** Integration tests were run against a limited SimpleMDM environment (a single supervised iPad running iOS 12.5, no macOS device). While **100% of endpoints are covered by unit tests** and the majority are validated through integration tests, some production scenarios could not be verified.

**Endpoints not integration tested:**

- 🖥️ **macOS only** — Remote desktop, firmware/recovery/admin passwords, FileVault, script jobs. Require an enrolled macOS device.
- 📜 **DDM (Declarative Device Management)** — Assigning custom declarations to a device requires iOS 15+. The test iPad runs iOS 12.
- ⛔ **Wipe / Unenroll** — Not tested as a precaution (destructive and irreversible).
- ⛔ **Push Certificate update** — Not tested (risk of breaking MDM communications).
- 🛡️ **Profiles / Device Groups** — Skipped if no profile or group is configured in the account.

**💡 Running tests with your own environment:**

```
# 1. Copy the environment file
cp .env.example .env

# 2. Set your SimpleMDM API key
# SIMPLEMDM_API_KEY=your-api-key

# 3. Delete cassettes to re-record with your environment
rm -rf tests/Fixtures/cassettes/*.json

# 4. Run tests
vendor/bin/pest
```

> 💡 **Tip:** VCR cassettes record real API responses. Once recorded, tests can be re-run without an API connection. Delete a cassette to force re-recording for that endpoint.

📖 OpenAPI Specification
-----------------------

[](#-openapi-specification)

An OpenAPI 3.0 specification file is available at [`openapi.yaml`](openapi.yaml). It covers all SimpleMDM API v1 endpoints documented in this SDK (~130 endpoints). This file can be used with AI CLI tools, Swagger UI, or any OpenAPI-compatible tool to explore and interact with the API.

> **Note:** This specification has been generated from the SDK source code and has not been extensively tested against the live API. Use it as a reference, not as a guaranteed contract.

📋 Requirements
--------------

[](#-requirements)

- PHP 8.1+
- Guzzle HTTP 7.0+

📄 License
---------

[](#-license)

MIT

###  Health Score

18

—

LowBetter than 8% of packages

Maintenance51

Moderate activity, may be stable

Popularity0

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity12

Early-stage or recently created project

 Bus Factor1

Top contributor holds 81.3% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

### Community

Maintainers

![](https://www.gravatar.com/avatar/a83b52919eaea900b98f8738a168c8ce47ecf7a90853959e1ad1af70246d3cfe?d=identicon)[dimer47](/maintainers/dimer47)

---

Top Contributors

[![dimer47](https://avatars.githubusercontent.com/u/12893613?v=4)](https://github.com/dimer47 "dimer47 (13 commits)")[![claude](https://avatars.githubusercontent.com/u/81847?v=4)](https://github.com/claude "claude (3 commits)")

### Embed Badge

![Health badge](/badges/dimer47-simplemdm-php-sdk/health.svg)

```
[![Health](https://phpackages.com/badges/dimer47-simplemdm-php-sdk/health.svg)](https://phpackages.com/packages/dimer47-simplemdm-php-sdk)
```

###  Alternatives

[exsyst/swagger

A php library to manipulate Swagger specifications

35916.4M7](/packages/exsyst-swagger)[hubspot/api-client

Hubspot API client

24016.2M20](/packages/hubspot-api-client)[pocketmine/bedrock-protocol

An implementation of the Minecraft: Bedrock Edition protocol in PHP

172445.0k14](/packages/pocketmine-bedrock-protocol)[botman/driver-telegram

Telegram driver for BotMan

93459.5k6](/packages/botman-driver-telegram)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
