PHPackages                             amondar-libs/php-postman - 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. amondar-libs/php-postman

ActiveLibrary[API Development](/categories/api)

amondar-libs/php-postman
========================

Allow to create postman documentation for your API

1.3.0(3mo ago)18↓77.8%PHPPHP ^8.3

Since Mar 18Pushed 2mo agoCompare

[ Source](https://github.com/amondar-libs/php-postman)[ Packagist](https://packagist.org/packages/amondar-libs/php-postman)[ RSS](/packages/amondar-libs-php-postman/feed)WikiDiscussions main Synced 3w ago

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

PHP Postman
===========

[](#php-postman)

[![PHP Version](https://camo.githubusercontent.com/ef0054230522e542bc1f908ac005c6c75888dea255bac910f9015e12095e31d7/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7068702d253545382e332d626c7565)](https://www.php.net/)[![Laravel](https://camo.githubusercontent.com/9bae2d9be2f5ba784143b82eae0b083e86e830cdaa9e751e8205adb30d882814/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c61726176656c2d3130253230253743253230313125323025374325323031322d726564)](https://laravel.com/)

A PHP package that generates [Postman](https://www.postman.com/) collections from your application routes. It supports Laravel out of the box and can be extended to work with any PHP framework.

Table of Contents
-----------------

[](#table-of-contents)

- [Installation](#installation)
- [Basic Usage](#basic-usage)
    - [Laravel Integration](#laravel-integration)
    - [Standalone CLI](#standalone-cli)
    - [Programmatic Usage](#programmatic-usage)
- [Deep Dive](#deep-dive)
    - [Authentication](#authentication)
    - [Route Macros (Laravel)](#route-macros-laravel)
    - [Route Filtering](#route-filtering)
    - [Form Data Attributes](#form-data-attributes)
    - [Descriptions](#descriptions)
    - [CLI Options Reference](#cli-options-reference)
- [Extending the Package](#extending-the-package)
    - [Custom Route Parser](#custom-route-parser)
    - [Custom Authentication](#custom-authentication)
    - [Custom Form Data Renderable](#custom-form-data-renderable)

---

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

[](#installation)

Install the package via Composer:

```
composer require amondar-libs/php-postman
```

Getting started
---------------

[](#getting-started)

The below example shows how to export a Postman collection from Laravel routes. But you can integrate this into your none-Laravel application by creating your RoutesParser class.

```
class ExportPostmanCollectionController
{
    public function __invoke(Router $router)
    {
        $export = cache()
            ->store('file')
            ->rememberForever('postman-collection', fn() => [
                'name'    => $name = now()->format('Y-m-d-H-i-s') . '-postman-collection.json',
                'content' => $this->export($router, $name),
            ]);

        return response()->streamDownload(
            function () use ($export) {
                echo $export['content'];
            },
            $export['name'],
            [
                'Content-Type' => 'application/json',
            ]
        );
    }

    private function export(RouteCollection $router, string $name): string
    {
        $routes = (new LaravelRoutesParser)->parseLaravelRoutes($router->getRoutes());

        return Export::from($routes->filterRoutes(
            RouteFilter::apply()
                ->affectedByPackage()
                ->byMiddleware('api')
        ), url('/'))
            ->parseDataIn(app_path())
            ->useOAuthTokenPath('/oauth/token')
            ->useDefaultAuth(
                new OAuthCodeWithPKCE(
                    callbackUrl: '{{base_url}}/auth/v1/callback',
                    authUrl: '{{base_url}}/oauth/authorize',
                    accessTokenUrl: '{{oauth_full_url}}',
                    state: 'development-state',
                    clientId: '{{postman_pkce_client_id}}',
                    tokenName: config('app.name') . ' PKCE Token'
                )
            )
            ->withGlobalVariables([
                'postman_pkce_client_id' => config('project.authentication.postman_pkce_client_id', ''),
            ])
            ->toJson($name);
    }
}
```

> Remember to add the optimize command in AppServiceProvider to clear the cache after each update in docker (of course if you're using it).

### Requirements

[](#requirements)

- PHP 8.3 or higher
- Laravel 10, 11, or 12 (for Laravel integration)

### Laravel Auto-Discovery

[](#laravel-auto-discovery)

The package ships with a Laravel service provider that is auto-discovered. No manual registration is needed. The service provider registers route macros (`alias`, `auth`, `description`, `additionalHeaders`, `structureDepth`) that you can use directly on your route definitions.

---

Basic Usage
-----------

[](#basic-usage)

### Laravel Integration

[](#laravel-integration)

The quickest way to export your Laravel routes to a Postman collection is via the built-in CLI binary:

```
./vendor/bin/postman export --laravel --base-url=https://api.example.com --output=postman.json
```

This will bootstrap your Laravel application, parse all registered routes, and write a Postman collection JSON file.

### Standalone CLI

[](#standalone-cli)

For non-Laravel projects, you can provide a custom route parser class:

```
./vendor/bin/postman export \
    --routes-parser="App\\Documentation\\MyRoutesParser" \
    --base-url=https://api.example.com \
    --output=postman.json
```

If `--routes-parser` is not provided and `--laravel` is not set, the CLI will interactively ask for the parser class name.

### Programmatic Usage

[](#programmatic-usage)

You can also generate collections programmatically in your PHP code:

```
use Amondar\Postman\Auth\Bearer;use Amondar\Postman\Export;use Amondar\Postman\Route\Route;use Amondar\Postman\Route\RouteCollection;

// Build a route collection
$routes = new RouteCollection();
$routes->push(new Route(
    name: 'users.index',
    path: 'api/users',
    methods: ['GET'],
    action: null,
));
$routes->push(new Route(
    name: 'users.store',
    path: 'api/users',
    methods: ['POST'],
    action: null,
));

// Export to JSON
$json = Export::from($routes, 'https://api.example.com')
    ->useDefaultAuth(Bearer::make('your-token'))
    ->withGlobalHeaders(['MY-HEADER' => 'my-value'])
    ->withGlobalVariables(['my_var' => 'my-value'])
    ->toJson('My API Collection');

file_put_contents('postman.json', $json);
```

#### Using with Laravel Routes Parser

[](#using-with-laravel-routes-parser)

```
use Amondar\Postman\Export;
use Amondar\Postman\Laravel\LaravelRoutesParser;

$parser = new LaravelRoutesParser();
$routes = $parser->parseLaravelRoutes(app('router')->getRoutes());

$json = Export::from($routes, config('app.url'))
    ->toJson('My Laravel API');
```

---

Deep Dive
---------

[](#deep-dive)

### Authentication

[](#authentication)

The package supports multiple authentication types that map directly to Postman's authentication options. Set a default auth for the entire collection or assign auth per route.

#### Bearer Token

[](#bearer-token)

```
use Amondar\Postman\Auth\Bearer;

$export = Export::from($routes, $baseUrl)
    ->useDefaultAuth(Bearer::make('optional-default-token'));
```

#### Basic Auth

[](#basic-auth)

```
use Amondar\Postman\Auth\Basic;

$export = Export::from($routes, $baseUrl)
    ->useDefaultAuth(Basic::make('username', 'password'));
```

#### OAuth 2.0 — Password Grant

[](#oauth-20--password-grant)

```
use Amondar\Postman\Auth\OAuthPassword;

$export = Export::from($routes, $baseUrl)
    ->useDefaultAuth(new OAuthPassword(
        clientId: 'your-client-id',
        clientSecret: 'your-client-secret',
        scope: 'read write',
    ))
    ->useOAuthTokenPath('/oauth/token');
```

#### OAuth 2.0 — Client Credentials

[](#oauth-20--client-credentials)

```
use Amondar\Postman\Auth\OAuthClientCredentials;

$export = Export::from($routes, $baseUrl)
    ->useDefaultAuth(new OAuthClientCredentials(
        clientId: 'your-client-id',
        clientSecret: 'your-client-secret',
        scope: 'read write',
    ))
    ->useOAuthTokenPath('/oauth/token');
```

#### OAuth 2.0 — Authorization Code with PKCE

[](#oauth-20--authorization-code-with-pkce)

```
use Amondar\Postman\Auth\OAuthCodeWithPKCE;

$export = Export::from($routes, $baseUrl)
    ->useDefaultAuth(new OAuthCodeWithPKCE(
        clientId: 'your-client-id',
        callbackUrl: 'https://app.example.com/callback',
        authUrl: 'https://auth.example.com/authorize',
        scope: 'openid profile',
    ))
    ->useOAuthTokenPath('/oauth/token');
```

#### No Authentication

[](#no-authentication)

```
use Amondar\Postman\Auth\None;

// This is the default — routes with no auth assigned will use None
$export = Export::from($routes, $baseUrl)
    ->useDefaultAuth(new None());
```

#### Per-Route Authentication (Laravel)

[](#per-route-authentication-laravel)

When using Laravel, you can set authentication on individual routes or route groups:

```
use Amondar\Postman\Auth\Bearer;
use Amondar\Postman\Auth\Basic;

// Single route
Route::get('/api/users', [UserController::class, 'index'])
    ->name('users.index')
    ->auth(Bearer::make());

// Route group
Route::auth(Basic::make())->group(function () {
    Route::get('/admin/dashboard', [AdminController::class, 'dashboard'])
        ->name('admin.dashboard');
});
```

### Route Macros (Laravel)

[](#route-macros-laravel)

The service provider registers several macros on Laravel's `Route`, `RouteRegistrar`, and `Router` classes:

#### `alias(string $alias)`

[](#aliasstring-alias)

Override the display name of a route in the Postman collection:

```
Route::get('/api/v2/users', [UserController::class, 'index'])
    ->name('api.v2.users.index')
    ->alias('List All Users');
```

#### `description(Stringable|string $description)`

[](#descriptionstringablestring-description)

Add a description to the route. Accepts a plain string, a `\Stringable` instance, or a class name that implements `Stringable`:

```
Route::get('/api/users', [UserController::class, 'index'])
    ->name('users.index')
    ->description('Returns a paginated list of all users.');
```

#### `structureDepth(int $depth)`

[](#structuredepthint-depth)

Control how deeply the route name is used for folder nesting in the Postman collection. By default, all segments except the last one are used as folder names:

```
// Route name: "api.v2.users.index"
// Default folders: api > v2 > users
// With structureDepth(0): api
// With structureDepth(1): api > v2
Route::get('/api/v2/users', [UserController::class, 'index'])
    ->name('api.v2.users.index')
    ->structureDepth(2);
```

#### `auth(AuthenticationContract $type)`

[](#authauthenticationcontract-type)

Set the authentication type for a route or route group (see [Authentication](#authentication)).

#### `additionalHeaders(array $headers)`

[](#additionalheadersarray-headers)

Add custom headers to the Postman request:

```
Route::get('/api/users', [UserController::class, 'index'])
    ->name('users.index')
    ->additionalHeaders([
        'X-Custom-Header' => 'custom-value',
        'Accept-Language' => 'en',
    ]);
```

### Route Filtering

[](#route-filtering)

Filter which routes are included in the exported collection. Filtering is available both via CLI options and programmatically.

#### CLI Filtering

[](#cli-filtering)

```
# Filter by path pattern
./vendor/bin/postman export --laravel --route-paths="api/*"

# Filter by route name
./vendor/bin/postman export --laravel --route-names="users.*"

# Filter by HTTP method. Case-insensitive.
./vendor/bin/postman export --laravel --route-methods="GET;POST"

# Filter by middleware
./vendor/bin/postman export --laravel --route-middlewares="auth:*"

# Combine multiple filters (all conditions must match)
./vendor/bin/postman export --laravel \
    --route-paths="api/*" \
    --route-methods="GET" \
    --route-middlewares="auth"
```

Multiple values can be separated by semicolons or passed as repeated options.

#### Programmatic Filtering

[](#programmatic-filtering)

```
use Amondar\Postman\Route\RouteFilter;

$filter = RouteFilter::apply()
    ->byPath('api/*')
    ->byMethod(['GET', 'POST'])
    ->byName('users.*')
    ->byMiddleware('auth');

$filteredRoutes = $routes->filterRoutes($filter)->values();

$json = Export::from($filteredRoutes, $baseUrl)->toJson();
```

### Form Data Attributes

[](#form-data-attributes)

Use the `#[PostmanFormData]` attribute to define request body data for your routes. The attribute can be applied to controller classes or methods and accepts either an inline array or a class implementing `Renderable`.

#### Inline Array

[](#inline-array)

```
use Amondar\Postman\Attributes\PostmanFormData;

class UserController
{
    #[PostmanFormData([
        'name' => 'John Doe',
        'email' => 'john@example.com'
    ])]
    public function store(Request $request)
    {
        // ...
    }
}
```

#### Using a Renderable Class

[](#using-a-renderable-class)

```
use Amondar\Postman\Attributes\PostmanFormData;
use Amondar\Postman\Contracts\Renderable;

class StoreUserFormData implements Renderable
{
    public function render(): array
    {
        // There can be complex logic to generate form data.
        // Also, you can use faker here.
        return [
            'name'  => 'John Doe',
            'email' => 'john@example.com',
            'role'  => 'admin',
        ];
    }
}

class UserController
{
    #[PostmanFormData(StoreUserFormData::class)]
    public function store(Request $request)
    {
        // ...
    }
}
```

To enable attribute scanning, specify the directories to scan using `parseDataIn()`:

```
$json = Export::from($routes, $baseUrl)
    ->parseDataIn('app/Http/Controllers', 'app/Http/Requests')
    ->toJson();
```

Or via CLI:

```
./vendor/bin/postman export --laravel --attributes-in=app/Domain --attributes-in=app/Infrastructure
```

### Descriptions

[](#descriptions)

Route descriptions support both plain strings and `Stringable` objects. This allows integration with markdown libraries or any custom description generator:

```
use Amondar\Postman\Contracts\Renderable;

// Plain string
Route::get('/api/users', [UserController::class, 'index'])
    ->description('Returns a list of users.');

// Stringable class (e.g., from amondar-libs/php-markdown)
Route::get('/api/users', [UserController::class, 'index'])
    ->description(Markdown::line('Returns a **list** of users.'));

// Class name that implements Stringable — will be instantiated automatically
Route::get('/api/users', [UserController::class, 'index'])
    ->description(UserIndexDescription::class);
```

### CLI Options Reference

[](#cli-options-reference)

OptionAliasDescription`--laravel`—Bootstrap and parse a Laravel application`--routes-parser``-parser`Fully qualified class name of a custom route parser`--attributes-in``-attributes`Directories to scan for `PostmanFormData` attributes (repeatable)`--collection-name``-name`Name of the Postman collection (default: `postman.json`)`--collection-description``-description`Description of the Postman collection`--base-url``-url`Base URL for requests, stored as `{{base_url}}` variable`--oauth-token-url``-oauth-url`OAuth token endpoint, stored as `{{oauth_full_url}}` variable`--headers``-H`Additional headers to be sent with each request. Example: --headers="X-Custom-Header: my-custom-header".`--variables``-VR`Additional variables to be sent on collection. Example: --variables="my\_var: my-value". Then in the collection you can use {{my\_var}} variable.`--route-paths``-paths`Filter routes by path patterns (semicolon-separated)`--route-names``-names`Filter routes by name patterns (semicolon-separated)`--route-methods``-methods`Filter routes by HTTP methods (semicolon-separated)`--route-middlewares``-middlewares`Filter routes by middleware (semicolon-separated)`--route-affected-only``-affected-only`Filter routes that are affected by the package. E.g. routes that have package attributes - alias, description, etc.`--output`—File path to write the collection to (prints to stdout if omitted)`--format`—Output format: `json` (default) or `pretty-json`---

Extending the Package
---------------------

[](#extending-the-package)

### Custom Route Parser

[](#custom-route-parser)

To support frameworks other than Laravel, implement the `RouteParserContract` interface:

```
use Amondar\Postman\Contracts\RouteParserContract;
use Amondar\Postman\Route\Route;
use Amondar\Postman\Route\RouteCollection;

class SymfonyRoutesParser implements RouteParserContract
{
    public function parse(string $rootPath): RouteCollection
    {
        $collection = new RouteCollection();

        // Parse your framework's routes and convert them
        foreach ($this->getSymfonyRoutes($rootPath) as $sfRoute) {
            $collection->push(new Route(
                name: $sfRoute->getName(),
                path: $sfRoute->getPath(),
                methods: $sfRoute->getMethods(),
                action: null, // or create a RouteAction if applicable
                middleware: [],
            ));
        }

        return $collection;
    }
}
```

Use it via CLI:

```
./vendor/bin/postman export \
    --routes-parser="App\\Documentation\\SymfonyRoutesParser" \
    --base-url=https://api.example.com
```

Or programmatically:

```
$parser = new SymfonyRoutesParser();
$routes = $parser->parse('/path/to/project/can/be/ignored');

$json = Export::from($routes, 'https://api.example.com')->toJson();
```

### Custom Authentication

[](#custom-authentication)

Create your own authentication type by implementing the `AuthenticationContract` interface:

```
use Amondar\Postman\Contracts\AuthenticationContract;

class ApiKeyAuth implements AuthenticationContract
{
    public function __construct(
        public readonly string $headerName = 'X-API-Key',
        public readonly ?string $value = null,
    ) {}

    public function toArray(): array
    {
        return [
            'type'   => 'apikey',
            'apikey' => [
                [
                    'key'   => 'key',
                    'value' => $this->headerName,
                    'type'  => 'string',
                ],
                [
                    'key'   => 'value',
                    'value' => $this->value ?? '',
                    'type'  => 'string',
                ],
                [
                    'key'   => 'in',
                    'value' => 'header',
                    'type'  => 'string',
                ],
            ],
        ];
    }
}
```

Then use it as default auth or per-route:

```
$export = Export::from($routes, $baseUrl)
    ->useDefaultAuth(new ApiKeyAuth('X-API-Key', 'secret'));

// Or in Laravel routes:
Route::get('/api/data', [DataController::class, 'index'])
    ->auth(new ApiKeyAuth());
```

### Custom Form Data Renderable

[](#custom-form-data-renderable)

Implement the `Renderable` interface to create reusable form data definitions:

```
use Amondar\Postman\Contracts\Renderable;

class PaginationFormData implements Renderable
{
    public function render(): array
    {
        return [
            'page' => 1,
            'per_page' => 15,
            'sort_by' => 'created_at',
            'sort_order' => 'desc',
        ];
    }
}
```

Then reference it in the `PostmanFormData` attribute:

```
use Amondar\Postman\Attributes\PostmanFormData;

class UserController
{
    #[PostmanFormData(PaginationFormData::class)]
    public function index()
    {
        // ...
    }
}
```

---

License
-------

[](#license)

Please see [LICENSE.md](LICENSE.md) for details.

###  Health Score

40

—

FairBetter than 86% of packages

Maintenance84

Actively maintained with recent releases

Popularity6

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity54

Maturing project, gaining track record

 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

7

Last Release

95d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/00b2e99bd1ba72674cf4370c0ef6e8efabebdd257036e5ed14020b5b487772b5?d=identicon)[amondar-libs](/maintainers/amondar-libs)

---

Top Contributors

[![amondar-libs](https://avatars.githubusercontent.com/u/3830450?v=4)](https://github.com/amondar-libs "amondar-libs (10 commits)")

###  Code Quality

TestsPest

Static AnalysisPHPStan, Rector

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/amondar-libs-php-postman/health.svg)

```
[![Health](https://phpackages.com/badges/amondar-libs-php-postman/health.svg)](https://phpackages.com/packages/amondar-libs-php-postman)
```

###  Alternatives

[spatie/laravel-responsecache

Speed up a Laravel application by caching the entire response

2.8k8.7M64](/packages/spatie-laravel-responsecache)[spatie/laravel-health

Monitor the health of a Laravel application

87411.3M152](/packages/spatie-laravel-health)[spatie/laravel-query-builder

Easily build Eloquent queries from API requests

4.5k29.4M279](/packages/spatie-laravel-query-builder)[illuminate/console

The Illuminate Console package.

13045.3M6.2k](/packages/illuminate-console)[psalm/plugin-laravel

Psalm plugin for Laravel

3345.1M337](/packages/psalm-plugin-laravel)[defstudio/telegraph

A laravel facade to interact with Telegram Bots

815320.5k3](/packages/defstudio-telegraph)

PHPackages © 2026

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