Skip to content

Laravel

Connect a Laravel workload and verify its first real signal.

Laravel is one optional integration target. Keep the ingestion credential in environment-backed configuration, deliver telemetry outside the business path, and verify the resulting LatidoFlow run.

Install the official Laravel package

The optional latidoflow/laravel adapter supports PHP ^8.3 and Laravel 13. The doctor workflow below requires version 1.1.0 or later. Install it from Packagist or inspect the GitHub source. The language-neutral REST examples below remain a complete supported path if you do not use the package.

composer require latidoflow/laravel:^1.1
php artisan latidoflow:install

# .env
LATIDOFLOW_TOKEN=replace-with-secret-store-value
LATIDOFLOW_ENDPOINT=https://www.latidoflow.com

Issue the workspace token from Workspace integration and keep it in environment-backed configuration. Read it through the published config/latidoflow.php. Never call env() from application services, and never log the token, heartbeat URLs, or query values.

Configured

The package is installed and the token exists in environment-backed configuration.

Instrumented

Named schedules or allowlisted queue jobs can emit the intended signal.

Active

LatidoFlow accepted a real heartbeat or lifecycle event from that execution path.

Operational

The signal, alert route, and response workflow have all been verified.

php artisan latidoflow:sync and php artisan latidoflow:verify prove authentication and definition synchronization. They do not prove that a workload executed. A passing unit test or labeled setup simulation is not production evidence. Finish with a natural scheduler or worker run and read the resulting LatidoFlow run.

Diagnose setup, then prove execution

Give an existing foreground scheduled command a safe, stable name in routes/console.php. Replace the example command and frequency with your actual workload. Queue jobs require an exact job-class allowlist in the package configuration.

use Illuminate\Support\Facades\Schedule;

Schedule::command('reports:daily')
    ->daily()
    ->name('Daily reports');
php artisan config:clear
php artisan latidoflow:sync --dry-run
php artisan latidoflow:doctor --skip-sync
php artisan latidoflow:doctor

The doctor checks definitions, token format, cache, queue connections, and public monitoring-pipeline health. Blockers return a nonzero exit code. --skip-sync leaves remote definitions unchanged; the final command synchronizes them using the configured workspace token. Health checks do not send that token.

If your deployment caches configuration, rebuild it with php artisan config:cache and restart long-running workers and scheduler processes. Wait for the normal scheduled execution or run an authorized queue workload, then open Workspace integration and inspect its newly accepted run. Check the workload identity, timestamp, terminal result, and any configured business-output assertions. Doctor success is not proof that the workload ran or an alert was delivered.

For a blocker, check the indicated configuration category and rerun the doctor. Do not share tokens, raw responses, or customer data. Keep your previous Composer lockfile and customer configuration for rollback; follow the package's upgrade, rollback, and removal instructions. Restoring the adapter does not undo hosted definitions or monitoring history.

Choose the smallest complete integration

Completion heartbeat

Best for a scheduled command that only needs to report a real successful completion and optional output.

Runtime lifecycle

Best when queued, started, retry, progress, skipped, and terminal evidence must remain distinct.

Definition sync

Best when deployment tooling should keep projects, environments, and monitor definitions aligned.

Store configuration outside application code

# .env
LATIDOFLOW_BASE_URL=https://www.latidoflow.com
LATIDOFLOW_INGESTION_TOKEN=replace-with-secret-store-value
LATIDOFLOW_HEARTBEAT_URL=replace-with-secret-monitor-url

// config/services.php
'latidoflow' => [
    'base_url' => env('LATIDOFLOW_BASE_URL', 'https://www.latidoflow.com'),
    'ingestion_token' => env('LATIDOFLOW_INGESTION_TOKEN'),
    'heartbeat_url' => env('LATIDOFLOW_HEARTBEAT_URL'),
],

Read environment values through configuration. Never call env() directly from application services, and never log these values.

Send a completion heartbeat out of band

After the business postcondition passes, enqueue a local telemetry job. The workload should not wait for LatidoFlow and should keep its original result if local telemetry enqueue is unavailable.

$result = $invoiceSync->run();

if ($result->recordsWritten() < 1) {
    throw new RuntimeException('Invoice sync produced no records.');
}

try {
    SendLatidoFlowHeartbeat::dispatch([
        'output' => ['records_written' => $result->recordsWritten()],
    ])->onQueue('telemetry');
} catch (Throwable) {
    // Keep the workload result; record only a constant safe diagnostic if required.
}

return $result;
use Illuminate\Support\Facades\Http;

public function handle(): void
{
    Http::acceptJson()
        ->asJson()
        ->connectTimeout(1)
        ->timeout(3)
        ->post(config('services.latidoflow.heartbeat_url'), $this->payload)
        ->throw();
}

Configure bounded job retries and backoff on the telemetry queue. Do not copy raw exceptions, serialized jobs, request payloads, command arguments, or customer records into the heartbeat payload.

Use an ordered outbox for the full lifecycle

Queued, start, heartbeat, log, success, failure, and skipped events need stable correlation and ordering. Persist the telemetry intent locally with the logical job ID, let one dispatcher send events in order, and attach the returned run_uuid to later transitions.

  • Generate the logical key before queue dispatch and reuse it across retries and redelivery.
  • Do not report failure for a released or retryable Laravel job. Report terminal failure only when the queue lifecycle declares the job failed.
  • Do not report success from a finally block. Verify the business postcondition first.
  • Let missing-heartbeat and timeout evaluation represent worker loss; a killed worker cannot reliably send a final event.

Follow the language-neutral Runtime signals guide for exact routes, statuses, idempotency, and proof states.

Synchronize definitions from deployment tooling

Scheduled commands are first-class heartbeat definitions. Keep the portable monitor type as heartbeat and describe the workload source separately in metadata.

{
  "project": {"name": "Billing", "slug": "billing"},
  "environment": {
    "name": "Production",
    "slug": "production",
    "kind": "production",
    "is_production": true
  },
  "monitors": [
    {
      "name": "Invoice synchronization",
      "slug": "invoice-sync",
      "type": "heartbeat",
      "check_interval_minutes": 15,
      "grace_seconds": 120,
      "timeout_seconds": 900,
      "metadata": {"source_kind": "scheduled"},
      "is_active": true
    }
  ]
}
$response = Http::baseUrl(config('services.latidoflow.base_url'))
    ->withToken(config('services.latidoflow.ingestion_token'))
    ->acceptJson()
    ->asJson()
    ->connectTimeout(1)
    ->timeout(3)
    ->retry([100, 500], throw: false)
    ->post('/api/v1/monitors/sync', $definitions);

$response->throw();

$monitorUuid = $response->json('monitors.0.uuid');

Run definition sync in deployment or integration tooling, not on every business request. Validate the exact payload against the OpenAPI schema and save returned UUIDs without logging the token. Definition sync does not prove execution; verify a natural run from the intended scheduler or worker.

Test the boundary

  • Use Http::fake() to assert method, path, authorization header, timeout behavior, and secret-free payloads.
  • Use queue fakes to prove the business path enqueues telemetry only after the success condition and preserves retry control flow.
  • Test remote failure separately and prove it does not change the business return value or exception.
  • Finish with a real worker or scheduler execution and read the resulting LatidoFlow run. A passing unit test proves instrumentation, not active production evidence.