1. Go to this page and download the library: Download kinetistack-io/php-sdk library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
kinetistack-io / php-sdk example snippets
use KinetiStack\Sdk\KinetiClient;
// Basic initialization
$client = new KinetiClient(
'https://api.kinetistack.io', // Your API host
'sk_test_12345' // Your project API key
);
// Advanced initialization with custom options and automatic retries
$client = new KinetiClient(
apiHost: 'https://api.kinetistack.io',
apiKey: 'sk_test_12345',
httpClient: null, // Optional: PSR-18 ClientInterface (e.g. Guzzle), Symfony HttpClientInterface, or auto-discovered
options: [
'timeout' => 30.0, // Request timeout in seconds
'max_retries' => 3, // Automatically retry transient HTTP 429 and 503 errors
]
);
// From a URL
$response = $client->analyzeImage('https://example.com/image.jpg', [
'page_title' => 'Renewable Energy'
]);
echo $response->altText;
if ($response->tokensConsumed !== null) {
echo "Tokens consumed: {$response->tokensConsumed}\n";
}
// From a stream resource (memory-efficient for large files & remote stream wrappers)
$stream = fopen('/path/to/image.jpg', 'rb');
$response = $client->analyzeImageStream($stream, 'image.jpg');
fclose($stream);
// From a local file (uses streams internally)
$response = $client->analyzeImageBinary('/path/to/image.jpg');
// From binary string content
$response = $client->analyzeImageContent($binaryData, 'image.jpg');
use KinetiStack\Sdk\Dto\ImageInputDto;
use KinetiStack\Sdk\Dto\JobDto;
use KinetiStack\Sdk\Exception\JobTimeoutException;
use KinetiStack\Sdk\KinetiClient;
// Submit a batch of images (URL or Base64 / Data URI)
$batch = $client->submitBatchJob([
new ImageInputDto('media:1', 'https://example.com/1.jpg'),
new ImageInputDto('media:2', imageBase64: 'data:image/jpeg;base64,...'),
]);
echo $batch->jobId; // E.g., '123e4567-e89b-12d3-a456-426614174000'
// Poll for completion with exponential backoff & jitter
try {
$completedBatch = $client->waitForJob(
jobId: $batch->jobId,
timeoutSeconds: KinetiClient::DEFAULT_TIMEOUT_SECONDS, // Default: 60s
pollIntervalSeconds: KinetiClient::DEFAULT_POLL_INTERVAL_SECONDS, // Default: 2s (initial interval)
onProgress: function (JobDto $job): void {
echo "Current status: {$job->status->value}\n";
},
maxPollIntervalSeconds: KinetiClient::DEFAULT_MAX_POLL_INTERVAL_SECONDS // Default: 10s (capped interval)
);
if ($completedBatch->tokensConsumed !== null) {
echo "Tokens consumed: {$completedBatch->tokensConsumed}\n";
}
foreach ($completedBatch->results as $result) {
echo $result->externalId . ': ' . $result->altText . "\n";
}
} catch (JobTimeoutException $e) {
echo "Job timed out. Last known status: " . $e->latestJob->status->value;
}
use KinetiStack\Sdk\Dto\RagStreamChunkDto;
use KinetiStack\Sdk\Dto\SearchQueryDto;
// 1. Standard search with optional synthesized answer
$query = SearchQueryDto::create('How does solar net metering work?')
->withLimit(5)
->withSynthesis(true);
$response = $client->search($query);
echo "Found {$response->total} results.\n";
if ($response->tokensConsumed !== null) {
echo "Tokens consumed: {$response->tokensConsumed}\n";
}
if ($response->hasSynthesis()) {
echo "Synthesized Answer: " . $response->synthesis->answer . "\n";
if ($response->synthesis->tokensConsumed !== null) {
echo "Synthesis Tokens: " . $response->synthesis->tokensConsumed . "\n";
}
}
// 2. Streamed RAG synthesis via PHP generator (reduces perceived latency)
$streamQuery = SearchQueryDto::create('Explain commercial solar financing options')
->withLimit(5)
->withStream(true);
/** @var \Generator<int, RagStreamChunkDto> $stream */
$stream = $client->searchStream($streamQuery);
foreach ($stream as $chunk) {
echo $chunk->text; // Streams partial tokens/words in real-time
if ($chunk->tokensConsumed !== null) {
echo "\nTokens consumed: {$chunk->tokensConsumed}\n";
}
flush();
}
use KinetiStack\Sdk\Exception\AuthenticationException;
use KinetiStack\Sdk\Exception\AuthorizationException;
use KinetiStack\Sdk\Exception\KinetiException;
use KinetiStack\Sdk\Exception\NotFoundException;
use KinetiStack\Sdk\Exception\PayloadTooLargeException;
use KinetiStack\Sdk\Exception\RateLimitException;
use KinetiStack\Sdk\Exception\ServerException;
use KinetiStack\Sdk\Exception\ServiceUnavailableException;
use KinetiStack\Sdk\Exception\ValidationException;
try {
$client->analyzeImage('invalid-url');
} catch (ValidationException $e) {
print_r($e->violations);
} catch (RateLimitException $e) {
// Thrown if max_retries is not configured or all retry attempts are exhausted
echo "Rate limited. Retry after: " . $e->retryAfter . " seconds.";
} catch (ServiceUnavailableException $e) {
// Thrown if max_retries is not configured or all retry attempts are exhausted
echo "Service temporarily unavailable (503): " . $e->getMessage();
} catch (KinetiException $e) {
echo "API Error: " . $e->getMessage();
}
use KinetiStack\Sdk\AdminClient;
// 1. Initial login without token
$admin = new AdminClient('https://api.kinetistack.io');
$auth = $admin->login('[email protected]', 'SuperSecret123!');
// 2. Obtain an immutable client instance with the JWT token
$authenticatedAdmin = $admin->withToken($auth->token);
// Or initialize directly if you already hold a valid token
$admin = new AdminClient('https://api.kinetistack.io', $jwtToken);
// Organizations are initialized during registration (POST /api/v1/admin/register).
// Once registered, manage your organization via item operations:
$orgId = 'org-uuid-123'; // Obtained from registration response or user profile
$currentOrg = $admin->getOrganization($orgId);
$updatedOrg = $admin->updateOrganization($orgId, ['name' => 'Acme Global Agency']);
// Projects
$project = $admin->createProject('Client Portal', 'portal.example.com', 'https://webhook.example.com/events');
$projects = $admin->listProjects();
$projectDetails = $admin->getProject($project->id);
$admin->updateProject($project->id, ['settings' => ['theme' => 'dark']]);
$admin->deleteProject($project->id); // Soft-delete and revokes associated API keys
// Create API key (returns ApiKeyCreatedDto with plaintext token)
$newKey = $admin->createApiKey($project->id, 'Production Drupal Key', 'all', rateLimitPerMinute: 120);
echo $newKey->token; // Secret plaintext token — save this now!
echo $newKey->tokenSuffix; // e.g. '1234'
// List API keys (returns ApiKeyDto[] without plaintext token, with optional usage metrics)
$keys = $admin->listApiKeys($project->id);
foreach ($keys as $key) {
$tokens = $key->tokensConsumedToday ?? 0;
$requests = $key->requestsToday ?? 0;
echo "{$key->name}: {$tokens} tokens consumed today across {$requests} requests\n";
}
// Rotate API key (old key continues working during grace period)
$rotated = $admin->rotateApiKey($project->id, $newKey->id);
echo $rotated->token; // New secret token
// Revoke API key
$admin->revokeApiKey($project->id, $newKey->id);
use KinetiStack\Sdk\AnalyticsClient;
use KinetiStack\Sdk\Enum\AnalyticsGrouping;
// Summary report across services (supports optional apiKeyId filter)
$usage = $admin->getUsage(from: '2026-09-01', to: '2026-09-05', projectId: $project->id, apiKeyId: $newKey->id);
foreach ($usage as $summary) {
echo "{$summary->projectName} - {$summary->service}: {$summary->totalTokens} tokens ({$summary->requestCount} requests)\n";
}
// Time-bucketed analytics with typed grouping (DAY, WEEK, MONTH) via AdminClient
$dailyAnalytics = $admin->getAnalytics(grouping: AnalyticsGrouping::DAY, from: '2026-09-01', to: '2026-09-07');
$weeklyAnalytics = $admin->getAnalytics(grouping: AnalyticsGrouping::WEEK, from: '2026-09-01', to: '2026-09-30');
$monthlyAnalytics = $admin->getAnalytics(grouping: AnalyticsGrouping::MONTH);
print_r($weeklyAnalytics->data);
// Or via dedicated AnalyticsClient
$analyticsClient = $admin->analytics();
// Or standalone: new AnalyticsClient('https://api.kinetistack.io', $jwtToken)
$trends = $analyticsClient->getAnalytics(AnalyticsGrouping::WEEK);
Loading please wait ...
Before you can download the PHP files, the dependencies should be resolved. This can take some minutes. Please be patient.