Error tracking
Capture unhandled JS errors with the browser SDK, or install the PHP or Laravel SDK for automatic backend exception capture.
Error tracking surfaces application errors — grouped by fingerprint, not a raw log dump — right on the site dashboard, and can trigger error rate alert rules.
Browser errors (JS SDK)
Add one script tag to your site, using the site's public key from its settings page:
<script src="https://downctl.com/sdk/downctl.js" data-key="YOUR_PUBLIC_KEY" defer></script>
That's it — it auto-initializes and starts capturing:
- Unhandled JS errors (
window.onerror) - Unhandled promise rejections
Errors are queued and flushed in the background, so page performance isn't affected.
Manual capture
The SDK exposes window.downctl for capturing errors and log messages yourself:
downctl.capture(new Error('something broke'), { userId: 42 });
downctl.log('warning', 'Low disk space', { disk: '95%' });
log() accepts error, warning, or info as the level. Context values are converted to strings automatically.
Backend errors (Laravel)
Install bluecapapps/downctl-laravel:
composer require bluecapapps/downctl-laravel
Add your site's secret key to .env:
DOWNCTL_API_KEY=your-secret-api-key
That's it — the package listens for Laravel's MessageLogged event and forwards anything at or above error level automatically, no exception handler changes required. Verify it's wired up with:
php artisan downctl:test
Capture manually with the facade when you want more control:
use Bluecapapps\DownctlLaravel\Facades\Downctl;
Downctl::captureException($e, context: ['order_id' => $order->id]);
Downctl::report('Stripe webhook signature invalid', level: 'error');
Other things worth knowing:
DOWNCTL_CAPTURE_LEVELcontrols the minimum level auto-captured (errorby default); set it blank to disable automatic capture and only report manually.DOWNCTL_QUEUE=truesends reports through your queue instead of a synchronous HTTP call, with 3 retries and a 30s backoff.- Context is redacted by default — high-confidence secret keys (
password,api_key,authorization, etc.) are stripped before anything is sent, at any nesting level. - The package also provides a
->cronMonitor()schedule macro — see API, port, ping, and cron monitors.
Visit the downctl-laravel GitHub repo for the full README, source, and issue tracker.
Backend errors (plain PHP)
Not on Laravel? Use bluecapapps/downctl-php directly — zero dependencies beyond the curl extension:
composer require bluecapapps/downctl-php
use Bluecapapps\Downctl\Client;
use Bluecapapps\Downctl\Config;
$client = new Client(Config::fromEnv()); // reads DOWNCTL_API_KEY from the environment
try {
riskyOperation();
} catch (\Throwable $e) {
$client->captureException($e, context: ['user_id' => $userId]);
}
By default the client is silent — network failures or a bad API key are swallowed so the SDK can never crash your app. Set silent: false locally to catch misconfiguration early.
Visit the downctl-php GitHub repo for the full README, source, and issue tracker.
Backend errors (raw API)
No PHP? Report directly to the API from any language using the site's secret key:
curl -X POST https://downctl.com/api/v1/errors \
-H "X-Downctl-Key: YOUR_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{
"level": "error",
"message": "RuntimeException: DB connection failed",
"stack_trace": "#0 app/Services/Db.php(42): ...",
"context": {"user_id": "123"}
}'
See the API reference for the full payload shape.
Grouping
Errors are grouped on a fingerprint derived from the message and the first stack trace line — repeated occurrences of the same error increment a counter on the dashboard instead of creating duplicate entries.
Next steps
- Set up an error rate alert rule to get notified when errors spike