codetech/laravel-api-logs
A lightweight Laravel package that logs every authenticated API request — URL, method, IP, payload, headers, response, and duration — linked to the user who made it. Sensitive values are redacted before storage, and a HasApiLogs trait exposes each user's history.
causer — so "buy" here means adopting ~a few hundred lines of MIT code instead of a sprint of internal work. Estimate the build honestly first: a competent Laravel dev can replicate the capture path in 1–2 days, but redaction-by-default, non-JSON response handling, and the guard configuration are where the real effort and the real bugs live.$user->apiLogs. This directly serves support workflows ("what did the customer's integration actually send?") and integration/partner onboarding, where the failure is usually on the caller's side.Authorization/Proxy-Authorization/Cookie/X-Api-Key/CSRF headers, response bodies (protecting token-issuing endpoints), and query strings in the stored URL. That moves "we log request bodies" from a security exception to a reviewable default, which is typically the gating decision for an audit-log feature.Consider it when:
terminate() — correct for latency, but it is one INSERT per authenticated request against your primary database. At high request rates this is a data-growth and index-maintenance decision, and the README documents no sampling rate or route allow/deny list. Verify those against the docs site; if they don't exist, plan a retention/purge job before launch.HasApiLogs trait being opt-in per model — with the documented consequence that authenticated models lacking the trait are silently not logged. That is a safe failure mode but a real observability gap; know which models you expect to appear.Look elsewhere when:
x_custom_auth or embedded in a free-text field will be stored in plaintext. That is the risk to escalate to Security before, not after, adoption.For executives: This is a small, MIT-licensed, drop-in component that gives us a per-customer record of every authenticated API call — what was sent, what came back, how long it took — with credentials automatically stripped before storage. It costs roughly half a day of engineering to adopt, requires no new infrastructure or vendor contract, and closes a recurring support gap where we currently cannot answer "what did their integration actually send?" It is small enough to fork and maintain ourselves if the upstream project stalls, so the downside is bounded. The one thing to fund alongside it is a retention policy, since it adds a row per API request.
For engineering: One middleware appended to the api group, a published migration, and a HasApiLogs trait on the authenticatable model. No container overrides, no queue, no external service. Capture runs in terminate() after the response is sent, so no user-facing latency — but it's a synchronous INSERT per authenticated request, so we own a growth curve and a retention job. Redaction is on by default (recursive key denylist for request/response/query string, header denylist for auth/cookie/API-key/CSRF), configurable via a publishable config file. We should pin the version, review what the denylist misses against our actual payload shapes, and be aware that the migration is publishable — meaning we own the table but the model and column contract stay upstream, so upgrades need coordination.
Positioning and risk statement: Upstream is a single agency (CodeTech, Portugal) with 0 stars and 0 dependents, currently at v3.2.0 with CI across PHP 8.2–8.4 × Laravel 11–13. Recommend adopting behind a pinned constraint with the expectation that we can vendor the code if needed. Do not adopt as a compliance control without a Security review of the redaction denylist against our own schemas.
How can I help you explore Laravel packages today?