PHPackages                             core45/laravel-kiriengine - 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. core45/laravel-kiriengine

ActiveLibrary[API Development](/categories/api)

core45/laravel-kiriengine
=========================

Laravel KIRI Engine API integration

1.1.7(10mo ago)027MITPHPPHP &gt;=8.1

Since Jun 11Pushed 10mo agoCompare

[ Source](https://github.com/core45/laravel-kiriengine)[ Packagist](https://packagist.org/packages/core45/laravel-kiriengine)[ RSS](/packages/core45-laravel-kiriengine/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (10)Dependencies (4)Versions (26)Used By (0)

Laravel KiriEngine Package
==========================

[](#laravel-kiriengine-package)

A Laravel package for integrating with the KIRI Engine API for 3D scanning and modeling. **Now with memory-efficient streaming uploads using cURL and multi-tenant support!**

Installation
------------

[](#installation)

```
composer require core45/laravel-kiriengine
```

Configuration
-------------

[](#configuration)

Publish the configuration file:

```
php artisan vendor:publish --provider="Core45\LaravelKiriengine\KiriengineServiceProvider"
```

Add your KIRI Engine API key to your `.env` file:

```
KIRIENGINE_API_KEY=your_api_key_here
KIRIENGINE_WEBHOOK_SECRET=your_webhook_secret_here
KIRIENGINE_WEBHOOK_PATH=kiri-engine-webhook
```

Quick Start
-----------

[](#quick-start)

### Fluent API Key Setting

[](#fluent-api-key-setting)

The easiest way to use KIRI Engine with a specific API key:

```
use Core45\LaravelKiriengine\Facades\Kiriengine;

// Set API key and chain methods
$result = Kiriengine::setApiKey('your_api_key_here')
    ->uploadPhotoScan()
    ->imageUpload($images);

// Clear the API key when done
Kiriengine::clearApiKey();
```

### Standard Usage

[](#standard-usage)

```
use Core45\LaravelKiriengine\Facades\Kiriengine;

// Uses configured API key (from .env or resolver)
$result = Kiriengine::uploadPhotoScan()->imageUpload($images);
```

Multi-Tenant Support
--------------------

[](#multi-tenant-support)

The package now supports multi-tenant applications where each user has their own KIRI Engine API key. You can easily configure the package to retrieve API keys from the authenticated user or any other source.

### Basic Multi-Tenant Setup

[](#basic-multi-tenant-setup)

1. **Add the API key column to your users table:**

```
php artisan make:migration add_kiri_api_key_to_users_table
```

```
// In the migration file
Schema::table('users', function (Blueprint $table) {
    $table->string('kiri_api_key')->nullable()->after('password');
});
```

2. **Update your User model:**

```
// In app/Models/User.php
protected $fillable = [
    'name',
    'email',
    'password',
    'kiri_api_key',
];

protected $hidden = [
    'password',
    'remember_token',
    'kiri_api_key', // Hide from serialization
];
```

3. **Configure the API key resolver in your config:**

```
// In config/laravel-kiriengine.php
'api_key_resolver' => function() {
    return auth()->user()->kiri_api_key ?? null;
},
```

### Advanced Multi-Tenant Configuration

[](#advanced-multi-tenant-configuration)

You can create more complex resolvers for different scenarios:

```
// Example: Check multiple sources
'api_key_resolver' => function() {
    // First try user-specific key
    if (auth()->check() && auth()->user()->kiri_api_key) {
        return auth()->user()->kiri_api_key;
    }

    // Then try organization key
    if (auth()->check() && auth()->user()->organization) {
        return auth()->user()->organization->kiri_api_key;
    }

    // Finally fall back to global key
    return null;
},

// Example: Database-based resolver
'api_key_resolver' => function() {
    return \App\Models\SystemSetting::where('key', 'kiri_api_key')
        ->where('user_id', auth()->id())
        ->value('value');
},

// Example: Cache-based resolver
'api_key_resolver' => function() {
    return cache()->remember("user_{auth()->id()}_kiri_key", 3600, function() {
        return auth()->user()->kiri_api_key;
    });
},
```

### Fallback Behavior

[](#fallback-behavior)

- If the resolver returns `null` or an empty string, the package will fall back to the `KIRIENGINE_API_KEY` environment variable
- If neither source provides a valid API key, an exception will be thrown with a clear error message

### Security Considerations

[](#security-considerations)

- API keys are automatically hidden from model serialization when added to the `$hidden` array
- Consider encrypting API keys in the database for additional security
- Use proper authentication middleware to ensure only authorized users can access the API

Using in Jobs and Commands
--------------------------

[](#using-in-jobs-and-commands)

When using KIRI Engine in jobs, commands, or other contexts where authentication isn't available, you can explicitly set the API key.

### Fluent API Key Setting (Recommended)

[](#fluent-api-key-setting-recommended)

```
use Core45\LaravelKiriengine\Facades\Kiriengine;

class ProcessKiriUploadJob implements ShouldQueue
{
    public function __construct(
        private string $apiKey,
        private array $images
    ) {}

    public function handle()
    {
        // Set API key and use KIRI Engine
        $result = Kiriengine::setApiKey($this->apiKey)
            ->uploadPhotoScan()
            ->imageUpload($this->images);

        // Clear the API key when done
        Kiriengine::clearApiKey();
    }
}
```

### Using the Trait

[](#using-the-trait)

1. **Add the trait to your job or command:**

```
use Core45\LaravelKiriengine\Traits\WithKiriEngineApiKey;

class ProcessKiriUploadJob implements ShouldQueue
{
    use WithKiriEngineApiKey;

    public function __construct(
        private int $userId,
        private array $images
    ) {}

    public function handle()
    {
        // Set API key from user ID
        $this->withUserIdKiriEngineApiKey($this->userId);

        // Now use KIRI Engine - it will use the user's API key
        $uploader = new UploadPhotoScan();
        $result = $uploader->imageUpload($this->images);

        // Clear the API key when done
        $this->clearKiriEngineApiKey();
    }
}
```

2. **Alternative ways to set the API key:**

```
// Set directly with API key string
$this->withKiriEngineApiKey('user_specific_api_key_here');

// Set from user model
$user = User::find($userId);
$this->withUserKiriEngineApiKey($user);

// Set from user ID (automatically fetches user)
$this->withUserIdKiriEngineApiKey($userId);
```

### Manual API Key Setting

[](#manual-api-key-setting)

You can also set the API key manually without using the trait:

```
use Core45\LaravelKiriengine\Services\KiriEngineApiKeyResolver;

class ProcessKiriUploadJob implements ShouldQueue
{
    public function handle()
    {
        // Set the API key explicitly
        KiriEngineApiKeyResolver::setApiKey('user_specific_api_key_here');

        // Use KIRI Engine
        $uploader = new UploadPhotoScan();
        $result = $uploader->imageUpload($this->images);

        // Clear when done
        KiriEngineApiKeyResolver::clearApiKey();
    }
}
```

### Command Example

[](#command-example)

```
use Core45\LaravelKiriengine\Facades\Kiriengine;

class ProcessUserUploadsCommand extends Command
{
    protected $signature = 'kiri:process-uploads {userId}';

    public function handle()
    {
        $userId = $this->argument('userId');
        $user = User::findOrFail($userId);

        // Set API key and process uploads
        $result = Kiriengine::setApiKey($user->kiri_api_key)
            ->uploadPhotoScan()
            ->imageUpload($this->getUserImages($userId));

        $this->info('Upload completed successfully!');
        Kiriengine::clearApiKey();
    }

    private function getUserImages(int $userId): array
    {
        // Your logic to get user images
        return [];
    }
}
```

### API Key Resolution Priority

[](#api-key-resolution-priority)

The package resolves API keys in this order:

1. **Explicitly set API key** (highest priority - for jobs, commands, etc.)
2. **Custom resolver function** (from config)
3. **Environment variable** (fallback)

Usage
-----

[](#usage)

### Photo Scanning

[](#photo-scanning)

```
use Core45\LaravelKiriengine\Facades\Kiriengine;

// With specific API key
$result = Kiriengine::setApiKey('user_api_key')
    ->uploadPhotoScan()
    ->imageUpload($images);

// With configured API key
$result = Kiriengine::uploadPhotoScan()->imageUpload($images);
```

### Object Scanning

[](#object-scanning)

```
use Core45\LaravelKiriengine\Facades\Kiriengine;

$result = Kiriengine::setApiKey('user_api_key')
    ->uploadObjectScan()
    ->imageUpload($images);
```

### 3DGS Scanning

[](#3dgs-scanning)

```
use Core45\LaravelKiriengine\Facades\Kiriengine;

$result = Kiriengine::setApiKey('user_api_key')
    ->upload3DgsScan()
    ->imageUpload($images);
```

### Model Status and Download

[](#model-status-and-download)

```
use Core45\LaravelKiriengine\Facades\Kiriengine;

// Get model status
$status = Kiriengine::setApiKey('user_api_key')
    ->model3d()
    ->getStatus('your_serial_number');

// Get download link for completed model
$downloadInfo = Kiriengine::setApiKey('user_api_key')
    ->model3d()
    ->getDownloadLink('your_serial_number');
```

### Balance Check

[](#balance-check)

```
use Core45\LaravelKiriengine\Facades\Kiriengine;

// Check your KIRI Engine balance
$balance = Kiriengine::setApiKey('user_api_key')
    ->balance()
    ->getBalance();
```

File Upload Methods
-------------------

[](#file-upload-methods)

The package supports multiple ways to provide files, with **file paths being the most memory-efficient**:

### 1. File Paths (Recommended - Memory Efficient)

[](#1-file-paths-recommended---memory-efficient)

```
// Direct file paths - streams from disk without loading into memory
$images = [
    '/absolute/path/to/image1.jpg',
    '/absolute/path/to/image2.jpg',
    'relative/path/to/image3.jpg', // relative to public directory
];
```

### 2. File Path Arrays

[](#2-file-path-arrays)

```
// File paths in arrays - also memory efficient
$images = [
    ['path' => '/path/to/image1.jpg', 'name' => 'custom_name1.jpg'],
    ['path' => '/path/to/image2.jpg'], // name defaults to basename
];
```

### 3. Content Arrays (Not Recommended for Large Files)

[](#3-content-arrays-not-recommended-for-large-files)

```
// Content arrays - loads entire file into memory (avoid for large files)
$images = [
    ['name' => 'image1.jpg', 'contents' => file_get_contents('/path/to/image1.jpg')],
    ['name' => 'image2.jpg', 'contents' => file_get_contents('/path/to/image2.jpg')],
];
```

Memory Optimization
-------------------

[](#memory-optimization)

**Important**: To avoid memory exhaustion when uploading many large files:

1. **Use file paths** instead of loading content into memory
2. **Process files in batches** if you have hundreds of files
3. **Avoid `file_get_contents()`** for large files

### Example: Processing Many Files

[](#example-processing-many-files)

```
// Good: Process in batches
$allImages = [/* array of file paths */];
$batchSize = 50;

for ($i = 0; $i < count($allImages); $i += $batchSize) {
    $batch = array_slice($allImages, $i, $batchSize);
    $result = Kiriengine::setApiKey('user_api_key')
        ->uploadPhotoScan()
        ->imageUpload($batch);
    // Process result...
}
```

### Example: Working with Spatie Laravel Medialibrary

[](#example-working-with-spatie-laravel-medialibrary)

```
// Get file paths from media library
$product = Menuproduct::find(4);
$images = [];

foreach ($product->modelscans as $photo) {
    $images[] = $photo->getPath(); // Returns full file path
}

$result = Kiriengine::setApiKey('user_api_key')
    ->uploadPhotoScan()
    ->imageUpload($images);
```

API Parameters
--------------

[](#api-parameters)

Different upload methods support different parameters based on the KIRI API endpoints:

### Photo Scanning Parameters:

[](#photo-scanning-parameters)

- `modelQuality` (0-3): High, Medium, Low, Ultra
- `textureQuality` (0-3): 4K, 2K, 1K, 8K
- `isMask` (0-1): Auto Object Masking Off/On
- `textureSmoothing` (0-1): Texture Smoothing Off/On
- `fileFormat`: Output format (obj, fbx, stl, ply, glb, gltf, usdz, xyz)

### Featureless Object Scanning Parameters:

[](#featureless-object-scanning-parameters)

- `fileFormat`: Output format (obj, fbx, stl, ply, glb, gltf, usdz, xyz)

### 3DGS Scanning Parameters:

[](#3dgs-scanning-parameters)

- `isMesh` (0-1): Turn off/on 3DGS to Mesh conversion
- `isMask` (0-1): Auto Object Masking Off/On
- `fileFormat` (string): Output format when isMesh=1 (obj, fbx, stl, ply, glb, gltf, usdz, xyz)

**Note**: Each scanning algorithm has different capabilities:

- **Photo Scan**: Full quality control with all parameters
- **Featureless Object Scan**: Only supports file format selection
- **3DGS Scan**: Supports mesh conversion and masking, file format only when isMesh=1

Webhooks
--------

[](#webhooks)

The package includes webhook support for receiving model processing updates. When a model is completed, KIRI Engine will send a webhook to your application.

### Setup Webhook Routes

[](#setup-webhook-routes)

The webhook route is automatically registered at `/kiri-engine-webhook` (configurable via `KIRIENGINE_WEBHOOK_PATH`).

### Webhook Event Handling

[](#webhook-event-handling)

The package dispatches a `KiriWebhookReceived` event when a webhook is received. You can listen to this event to process completed models:

```
// In your EventServiceProvider
protected $listen = [
    \Core45\LaravelKiriengine\Events\KiriWebhookReceived::class => [
        \Core45\LaravelKiriengine\Listeners\ProcessKiriWebhook::class,
    ],
];
```

### Custom Webhook Processing

[](#custom-webhook-processing)

The included `ProcessKiriWebhook` listener automatically:

- Downloads completed models
- Extracts ZIP files
- Saves files to storage
- Handles errors and retries

You can create your own listener to customize the processing:

```
class CustomWebhookListener
{
    public function handle(KiriWebhookReceived $event)
    {
        $payload = $event->payload;

        // Process the webhook data
        if (isset($payload['id'])) {
            $modelId = $payload['id'];
            // Your custom logic here
        }
    }
}
```

Error Handling
--------------

[](#error-handling)

The package throws `KiriengineException` for API errors:

```
try {
    $result = $uploader->imageUpload($images);
} catch (KiriengineException $e) {
    // Handle API errors
    Log::error('KIRI Engine error: ' . $e->getMessage());
}
```

Requirements
------------

[](#requirements)

- Laravel 9+
- PHP 8.1+
- cURL extension (usually included with PHP)
- At least 20 images per upload (maximum 300)

Technical Details
-----------------

[](#technical-details)

This package uses **cURL with CURLFile** for memory-efficient file uploads:

- Files are streamed directly from disk without loading into memory
- Uses `CURLFile` class for proper multipart form data handling
- 15-minute timeout for large uploads
- Automatic MIME type detection
- Support for temporary files for content arrays

Available Methods
-----------------

[](#available-methods)

Kiriengine API is divided into six main parts:

- Photo Scan Upload
- Featureless Object Scan Upload
- 3DGS Scan Upload
- Model Status and Get Download Link
- Balance
- Webhook

To access any of the methods use `Kiriengine` facade and use one of the main shortcut methods followed by the API method name:

- `Kiriengine::uploadPhotoScan()->...`
- `Kiriengine::uploadObjectScan()->...`
- `Kiriengine::upload3DgsScan()->...`
- `Kiriengine::model3d()->...`
- `Kiriengine::balance()->...`

### All of the available methods you can find in Kiriengine API docs:

[](#all-of-the-available-methods-you-can-find-in-kiriengine-api-docs)

If you find any errors or would like to help with improving and maintaining the package please leave the comment.

License
-------

[](#license)

This package is open-sourced software licensed under the [MIT license](LICENSE).

###  Health Score

33

—

LowBetter than 75% of packages

Maintenance54

Moderate activity, may be stable

Popularity7

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity55

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% 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.

###  Release Activity

Cadence

Every ~1 days

Total

25

Last Release

317d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/4f051e223739810bf8ae8581a9d63185ca4056a751c4101d35c29e1ca799205f?d=identicon)[core45](/maintainers/core45)

---

Top Contributors

[![mirouse](https://avatars.githubusercontent.com/u/2631240?v=4)](https://github.com/mirouse "mirouse (42 commits)")

###  Code Quality

TestsPest

### Embed Badge

![Health badge](/badges/core45-laravel-kiriengine/health.svg)

```
[![Health](https://phpackages.com/badges/core45-laravel-kiriengine/health.svg)](https://phpackages.com/packages/core45-laravel-kiriengine)
```

###  Alternatives

[darkaonline/l5-swagger

OpenApi or Swagger integration to Laravel

2.9k34.0M112](/packages/darkaonline-l5-swagger)[echolabsdev/prism

A powerful Laravel package for integrating Large Language Models (LLMs) into your applications.

2.3k388.3k10](/packages/echolabsdev-prism)[sburina/laravel-whmcs-up

WHMCS API client and user provider for Laravel

271.3k](/packages/sburina-laravel-whmcs-up)

PHPackages © 2026

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