zeridion/flare

Official PHP SDK for the Zeridion Flare managed background-jobs API

v0.2.0 2026-07-20 00:30 UTC

This package is auto-updated.

Last update: 2026-08-20 02:54:06 UTC


README

PHP SDK for the Zeridion Flare managed background-jobs API.

Packagist License: MIT

Full documentation at docs.zeridion.com/flare

Installation

composer require zeridion/flare-php

Requires PHP 8.2+, ext-curl, and ext-json. Zero third-party dependencies — uses curl directly, no Guzzle / Symfony HTTP coupling.

Quick start

use Zeridion\Flare\FlareClient;

$client = new FlareClient(apiKey: 'zf_live_sk_...');
// Or, with FLARE_API_KEY set in the environment:
//   $client = new FlareClient();

$job = $client->createJob([
    'job_type' => 'SendWelcomeEmail',
    'payload'  => ['email' => 'alice@example.com'],
    'queue'    => 'default',
]);

echo $job['id'], ' ', $job['state'];  // "job_abc123 pending"

new FlareClient(...)

Argument Type Default Notes
apiKey ?string getenv('FLARE_API_KEY') Required — pass directly or via env var
baseUrl string https://api.zeridion.com Override for dev / staging environments
maxRetries int 3 Set 0 to disable retries
retryBaseDelayMs int 500 Base for exponential schedule (ms)
retryMaxDelayMs int 30000 Cap on any single backoff wait
timeoutSeconds float 30.0 Per-request curl timeout
transport ?HttpTransport new CurlTransport() Swap in for tests or to plug in a logging proxy

Methods

Every public method accepts optional idempotencyKey and requestId parameters, sent as the Idempotency-Key and X-Request-Id headers respectively.

$client->createJob($body, idempotencyKey: 'optional', requestId: 'optional');
$client->getJob($id);                       // returns null if 404
$client->listJobs(state: 'failed', limit: 25);
$client->cancelJob($id);                    // returns null if 409
$client->retryJob($id);                     // returns null if 409
$client->registerWorker($body);             // worker-side
$client->pollWorkers($body);                // worker-side
$client->heartbeat($body);                  // worker-side
$client->ackWorker($body);                  // worker-side

Most apps will use the built-in worker runtime rather than calling the low-level worker methods directly.

Automatic retries

The SDK auto-retries HTTP 429 / 502 / 503 / 504 responses and transient network errors (curl errors caught from CurlTransport) with full-jitter exponential backoff capped at retryMaxDelayMs. The Retry-After response header is honored when present (integer seconds).

See the stable error-code registry for every error.code string the API can return.

Error handling

All API errors extend FlareException. Typed subclasses let you discriminate:

use Zeridion\Flare\{FlareClient, FlareException, AuthException, RateLimitException, ConflictException};

try {
    $client->createJob(['job_type' => 'MyJob']);
} catch (RateLimitException $e) {
    sleep($e->retryAfter ?? 1);  // honor X-RateLimit-Reset (epoch)
} catch (AuthException $e) {
    // 401 — invalid API key
} catch (ConflictException $e) {
    if ($e->errorCode === 'idempotency_key_reuse') {
        // Same Idempotency-Key reused with a different body
    }
} catch (FlareException $e) {
    echo "Error {$e->statusCode}: {$e->errorCode}{$e->getMessage()} (req {$e->requestId})";
}

Each FlareException exposes $statusCode, $errorCode, $requestId and the parent \Exception::getMessage(). (Property is named errorCode not code because PHP's \Exception already declares a non-readonly $code that a readonly string can't redeclare.)

Verifying webhook signatures

If you've configured outbound webhooks via the /flare/v1/webhooks API, verify the X-Zeridion-Signature header on each incoming delivery:

use Zeridion\Flare\Webhook;

$body   = file_get_contents('php://input');
$header = $_SERVER['HTTP_X_ZERIDION_SIGNATURE'] ?? '';

if (!Webhook::verify($body, $header, $secret, toleranceSeconds: 300)) {
    http_response_code(400);
    exit('invalid signature');
}
// ... process the event ...

Webhook::verify is HMAC-SHA256 over <unix_timestamp>.<raw_body>, constant-time-compared (via hash_equals) against every v1= value in the header (supports secret rotation). The optional toleranceSeconds parameter rejects replays older than that.

Background worker

The package ships a built-in worker under the Zeridion\Flare\Worker namespace. Define your jobs as classes decorated with #[FlareJob], register them, and the worker registers itself, long-polls for work, dispatches each job to its handler, heartbeats with progress, honours server cancellation, and drains the in-flight job on SIGTERM / SIGINT.

use Zeridion\Flare\Worker\{FlareJob, FlareWorker, Job, JobContext, RecurringJob, WorkerOptions};

#[FlareJob(queue: 'email', maxAttempts: 5, timeoutSeconds: 60)]
final class SendWelcomeEmail implements Job
{
    public function handle(mixed $payload, JobContext $ctx): void
    {
        if ($this->alreadySent($ctx->jobId)) return;   // at-least-once → idempotent
        $this->mailer->send($payload['email']);
        $ctx->reportProgress(1.0);
    }
}

#[FlareJob(cron: '0 3 * * *', queue: 'maintenance', timezone: 'UTC')]
final class NightlyCleanup implements RecurringJob
{
    public function handle(JobContext $ctx): void { $this->purgeExpired(); }
}

$worker = new FlareWorker(WorkerOptions::fromEnv());
$worker->register(SendWelcomeEmail::class);
$worker->register(NightlyCleanup::class);
exit($worker->run());

Notes:

  • One job per process. Stock PHP has no shared-memory threads, so the worker runs one job at a time. Scale out with multiple processes under a supervisor.
  • Optional ext-pcntl / ext-posix enable background heartbeats and graceful SIGTERM shutdown. Without them the worker still runs, with coarser liveness and no preemptive cancellation.
  • Cooperative cancellation. Long-running handlers should poll $ctx->cancellationRequested() and unwind on their own.
  • At-least-once delivery. Make handlers idempotent (guard on $ctx->jobId).

A ready-to-run worker also ships via the bin/flare-work command (discovers #[FlareJob] classes and runs the worker from environment configuration).

Full guide: docs.zeridion.com/flare/sdks/php/worker.

Sample app

A runnable worker starter (a payload job, a recurring job, progress, and graceful drain, plus a feeder) lives at samples/php-starter/.

Links