PHPackages                             zidbih/laravel-liveapi - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [API Development](/categories/api)
4. /
5. zidbih/laravel-liveapi

ActiveLibrary[API Development](/categories/api)

zidbih/laravel-liveapi
======================

Generate accurate OpenAPI specifications by observing real Laravel API traffic at runtime, with zero configuration and no annotations.

v0.1.1(5mo ago)51MITPHPPHP ^8.2

Since Jan 8Pushed 5mo agoCompare

[ Source](https://github.com/medmahmoudhdaya/laravel-liveapi)[ Packagist](https://packagist.org/packages/zidbih/laravel-liveapi)[ RSS](/packages/zidbih-laravel-liveapi/feed)WikiDiscussions main Synced today

READMEChangelogDependencies (8)Versions (3)Used By (0)

Laravel LiveApi
===============

[](#laravel-liveapi)

Accurate OpenAPI 3.1 generation by observing real API traffic at runtime.
Zero annotations. Minimal configuration. Hard-disabled in production.

---

What is Laravel LiveApi?
------------------------

[](#what-is-laravel-liveapi)

Laravel LiveApi generates an OpenAPI specification by **observing real requests and real responses** while you use your API during development or testing.

You do not describe your API.
You do not annotate your code.
You simply **use your API**, and documentation is produced as a side effect.

If the API runs, LiveApi can document it.

---

Installation
------------

[](#installation)

Install the package as a development dependency:

```
composer require zidbih/laravel-liveapi --dev
```

Publish the configuration file (recommended):

```
php artisan vendor:publish --tag=liveapi-config
```

No further setup is required.

---

Zero configuration workflow
---------------------------

[](#zero-configuration-workflow)

1. Make requests to your API using:

    - Postman
    - Swagger UI
    - Browser
    - Automated tests
2. LiveApi observes:

    - request headers
    - query parameters
    - request body
    - response status codes
    - response JSON structure
3. Generate the OpenAPI specification:

```
php artisan liveapi:generate
```

You now have a deterministic `openapi.json` file that reflects what your API actually does.

---

Dashboard
---------

[](#dashboard)

Laravel LiveApi exposes a local dashboard at `/liveapi` that renders the generated OpenAPI specification, with the raw spec available at `/liveapi/openapi.json`. The dashboard is enabled only in local and testing environments and uses Swagger UI by default as a viewer. It requires no configuration and reflects the API’s actual runtime behavior inferred from real requests and responses. The dashboard is intentionally thin — the generated `openapi.json` file remains the primary output and can be consumed by any OpenAPI-compatible tool.

> Example of the Swagger UI dashboard rendering an OpenAPI specification inferred from real API traffic during local development.

[![Swagger dashboard](docs/images/swagger-dashboard.png)](docs/images/swagger-dashboard.png)

---

Environment configuration (optional)
------------------------------------

[](#environment-configuration-optional)

Laravel LiveApi works out of the box with **zero configuration**.
You do **not** need to define any environment variables to start using it.

The variables below are **optional** and can be used only if you want to **override the default behavior or metadata**.

```
# Enable or disable LiveApi entirely (ignored in production)
LIVEAPI_ENABLED=true

# Freeze schema evolution (read-only mode)
LIVEAPI_FROZEN=false

# Customize OpenAPI metadata
LIVEAPI_TITLE="My Application API"
LIVEAPI_DESCRIPTION="Generated by Laravel LiveApi"
LIVEAPI_VERSION="0.1.0"

# Base URL used in the OpenAPI servers section
LIVEAPI_BASE_URL=http://localhost
```

Sensitive data masking
----------------------

[](#sensitive-data-masking)

Laravel LiveApi is designed to be safe by default.
Before any request or response payload is written to disk, sensitive fields are automatically masked to prevent secrets from being persisted in snapshot files.

Masking is read-only and never affects the actual request or response returned by your application.

---

### Default masked fields

[](#default-masked-fields)

Out of the box, Laravel LiveApi masks the following fields:

- `password`
- `password_confirmation`
- `token`
- `card_number`

When one of these fields is encountered anywhere in a JSON payload, its value is replaced with:

```
"*****"
```

The field name and structure are preserved, but the original value is never stored.

---

### How masking works

[](#how-masking-works)

- Masking is applied to both request and response bodies
- Masking is applied recursively to nested objects and arrays
- Field name matching is case-insensitive
- Only values are masked; keys and structure remain intact

This allows schemas to be inferred correctly without exposing sensitive data.

---

### Adding or removing masked fields

[](#adding-or-removing-masked-fields)

You can customize the list of masked fields in the configuration file (make sure you have published the configuration file first):

```
php artisan vendor:publish --tag=liveapi-config
```

```
// config/liveapi.php

'mask_fields' => [
    'password',
    'password_confirmation',
    'token',
    'card_number',
    'api_key',
    'secret',
],
```

Any field name added to this list will be masked automatically.
Removing a field from the list will allow its value to be captured.

---

### Headers and sensitive metadata

[](#headers-and-sensitive-metadata)

Laravel LiveApi does not record sensitive headers such as:

- `Authorization`
- `Cookie`
- CSRF-related headers

These headers are excluded by design and cannot be captured accidentally.

---

### Security guarantees

[](#security-guarantees)

- Sensitive values are masked before snapshots are written to disk
- No raw secrets are ever stored
- Requests and responses are never mutated
- Masking cannot be disabled per request
- Production traffic is never captured

This behavior is enforced consistently and does not rely on developer discipline.

How it works
------------

[](#how-it-works)

- A global middleware intercepts all `api/*` routes
- Each request/response pair becomes a snapshot
- Multiple snapshots for the same route are merged
- The schema is inferred deterministically:
    - field types
    - required vs optional fields
    - nullable fields
    - multiple response variants
- Authentication context is tracked separately

The running API is the source of truth.

---

Example
-------

[](#example)

### Route definition

[](#route-definition)

```
Route::get('/api/users/profile', function (Request $request) {
    $data = [
        'id' => 1,
        'username' => 'zidbih',
    ];

    if ($request->has('extra')) {
        $data['bio'] = 'Software Engineer';
    }

    return response()->json($data);
});
```

### Observed behavior

[](#observed-behavior)

- Request without `extra`:

```
{ "id": 1, "username": "zidbih" }
```

- Request with `?extra=1`:

```
{ "id": 1, "username": "zidbih", "bio": "Software Engineer" }
```

### Generated schema

[](#generated-schema)

```
{
    "method": "GET",
    "uri": "api/users/profile",
    "authenticated": false,
    "query_params": {
        "extra": {
            "type": "string",
            "example": "1"
        }
    },
    "request_body": [],
    "responses": {
        "200": {
            "description": "Automated response inference",
            "content": {
                "application/json": {
                    "schema": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "integer"
                            },
                            "username": {
                                "type": "string"
                            },
                            "bio": {
                                "type": "string"
                            }
                        },
                        "required": [
                            "id",
                            "username"
                        ],
                        "additionalProperties": false
                    }
                }
            }
        }
    }
}
```

Optional fields are inferred automatically.

---

Commands
--------

[](#commands)

### Generate OpenAPI specification

[](#generate-openapi-specification)

```
php artisan liveapi:generate
```

Compiles all captured snapshots into a single `openapi.json` file.

---

### Show status

[](#show-status)

```
php artisan liveapi:status
```

Displays:

- current environment
- enabled / frozen state
- number of captured routes
- snapshot count
- whether `openapi.json` exists

---

### Clear snapshots

[](#clear-snapshots)

```
php artisan liveapi:clear
```

Delete all recorded snapshots.

Delete snapshots and the generated spec:

```
php artisan liveapi:clear --spec
```

---

Freeze mode
-----------

[](#freeze-mode)

Once your API contract is stable, you can freeze schema evolution:

```
LIVEAPI_FROZEN=true
```

When frozen:

- no new snapshots are recorded
- existing schemas are not modified
- the dashboard remains accessible
- `liveapi:generate` continues to work

Freeze mode turns LiveApi into a read-only documentation system.

---

Production safety
-----------------

[](#production-safety)

Laravel LiveApi is hard-disabled in production.

- no middleware capture
- no snapshot writes
- no override flag

This guarantee is enforced at multiple layers.

---

Storage model
-------------

[](#storage-model)

All data is stored as plain JSON:

```
storage/liveapi/
├── snapshots/
│   ├── get-47421dd7d271091c5fba4fbe363a48daab5c155/
│   │   ├── guest.json
│   │   └── auth.json
│   ├── post-a1b2c3d4e5f6.../
│   │   ├── guest.json
│   │   └── auth.json
│   └── ...
└── openapi.json

```

The files are human-readable, diffable, and git-friendly.

---

Using the generated OpenAPI file
--------------------------------

[](#using-the-generated-openapi-file)

The generated `openapi.json` can be consumed by:

- Swagger UI
- Postman
- Redoc
- Stoplight
- Client SDK generators
- API gateways
- Contract testing tools

Laravel LiveApi does not lock you into any viewer.

---

Testing and quality
-------------------

[](#testing-and-quality)

- Fully tested with Pest
- Uses Orchestra Testbench
- Freeze and production guarantees are covered
- Tests assert behavior, not internals

---

When should you use this?
-------------------------

[](#when-should-you-use-this)

Laravel LiveApi is useful when:

- APIs evolve frequently
- documentation drift is a problem
- client SDKs rely on OpenAPI
- accuracy matters more than annotations

It does not replace Postman or Swagger.
It makes their usage produce accurate documentation automatically.

---

License
-------

[](#license)

MIT License.

---

Philosophy
----------

[](#philosophy)

Documentation should be observed, not declared.

Laravel LiveApi exists to keep API documentation accurate, boring, and trustworthy.

###  Health Score

32

—

LowBetter than 69% of packages

Maintenance70

Regular maintenance activity

Popularity6

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity38

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~0 days

Total

2

Last Release

176d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/b8435c1650e36d1af5d86c9955e343d4ce94ad62949a09e43c4f5cc1a47dba79?d=identicon)[medmahmoudhdaya](/maintainers/medmahmoudhdaya)

---

Top Contributors

[![medmahmoudhdaya](https://avatars.githubusercontent.com/u/192469611?v=4)](https://github.com/medmahmoudhdaya "medmahmoudhdaya (24 commits)")

---

Tags

apilaravelswaggeropenapiruntimedeveloper-toolsapi-documentationzero-configopenapi-3schema-inference

###  Code Quality

TestsPest

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/zidbih-laravel-liveapi/health.svg)

```
[![Health](https://phpackages.com/badges/zidbih-laravel-liveapi/health.svg)](https://phpackages.com/packages/zidbih-laravel-liveapi)
```

###  Alternatives

[psalm/plugin-laravel

Psalm plugin for Laravel

3355.3M345](/packages/psalm-plugin-laravel)[api-platform/laravel

API Platform support for Laravel

58171.5k14](/packages/api-platform-laravel)[laravel/mcp

Rapidly build MCP servers for your Laravel applications.

77022.3M151](/packages/laravel-mcp)[laravel/cashier

Laravel Cashier provides an expressive, fluent interface to Stripe's subscription billing services.

2.6k29.9M146](/packages/laravel-cashier)[laravel/pulse

Laravel Pulse is a real-time application performance monitoring tool and dashboard for your Laravel application.

1.7k15.1M132](/packages/laravel-pulse)[nuwave/lighthouse

A framework for serving GraphQL from Laravel

3.5k11.8M117](/packages/nuwave-lighthouse)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
