PHP SDK
A small client you can copy into your backend. This is a documented implementation, not a separately published package. It sends the same API envelope for every service through one call method.
PHP 8.0+ with HTTPS stream wrappers enabled (allow_url_fopen). No third-party package is required.
Response contract
| Field | Meaning |
|---|---|
data | Operation result; absent on API errors |
error | API error object, or null/nil on success; message is the stable code |
meta | Response metadata, including pagination when returned |
exec_time | Gateway execution time in seconds, when returned |
API errors return in Result.error. Network, invalid JSON, and transport failures raise an exception or return a Go error. These small clients do not manage sessions, auto-refresh tokens, or retry requests. Pass a current user bearer token to the constructor/client only when acting as that user; omit it for trusted server/agent calls. Keep keys on the server.
Client implementation
Save as singlebase.php. Download the source.
php
<?php
// PHP 8.0+, with HTTPS support enabled for stream wrappers.
class Result {
public mixed $data;
public ?array $error;
public array $meta;
public ?float $exec_time;
public function __construct(array $body) {
$this->data = $body['data'] ?? null;
$this->error = $body['error'] ?? null;
$this->meta = $body['meta'] ?? [];
$this->exec_time = isset($body['exec_time']) ? (float)$body['exec_time'] : null;
}
}
class SinglebaseClient {
public function __construct(private string $api_key, private string $api_url, private ?string $bearer = null) {}
public function call(string $operation, array $payload, ?array $options = null): Result {
$headers = ['Content-Type: application/json', 'X-API-KEY: ' . $this->api_key];
if ($this->bearer !== null) $headers[] = 'Authorization: Bearer ' . $this->bearer;
$body = ['operation' => $operation, 'payload' => (object)$payload];
if ($options !== null) $body['options'] = (object)$options;
$context = stream_context_create(['http' => [
'method' => 'POST', 'header' => implode("\r\n", $headers),
'content' => json_encode($body, JSON_THROW_ON_ERROR),
'timeout' => 30, 'ignore_errors' => true, 'follow_location' => 0
]]);
$raw = file_get_contents($this->api_url, false, $context);
if ($raw === false) throw new RuntimeException('HTTP transport failed');
$decoded = json_decode($raw, true, 512, JSON_THROW_ON_ERROR);
if (!is_array($decoded)) throw new RuntimeException('Expected a JSON API envelope');
$status = 0;
foreach ($http_response_header ?? [] as $line) {
if (preg_match('/^HTTP\/\S+\s+(\d{3})/', $line, $m)) $status = (int)$m[1];
}
if ($status >= 400 && !isset($decoded['error'])) throw new RuntimeException('HTTP ' . $status . ' without an API error envelope');
return new Result($decoded);
}
}Example
Set SINGLEBASE_API_URL to the complete console endpoint and SINGLEBASE_API_KEY to your server or appropriately scoped agent key. The notes collection must exist.
php
<?php
require 'singlebase.php';
$sbc = new SinglebaseClient(getenv('SINGLEBASE_API_KEY'), getenv('SINGLEBASE_API_URL'));
$resp = $sbc->call('data.query', ['collection' => 'notes', 'limit' => 5], []);
if ($resp->error !== null) throw new RuntimeException($resp->error['message']);
var_dump($resp->data, $resp->meta, $resp->exec_time);Use the same method with llm.summarize for generation or chat.ask for an answer, with the operation's verified payload. The options argument goes in the request envelope, separate from payload. An empty options object is valid; omit it when unused. See API overview for request access and errors, and API reference for the operation groups.