bhaveshsoni26/laravel-postman-sync

Automatically scan Laravel API routes and generate a Postman Collection, environment, docs and tests.

Maintainers

Package info

github.com/Bhaveshsoni26/Laravel-Postman-Sync

pkg:composer/bhaveshsoni26/laravel-postman-sync

Transparency log

Statistics

Installs: 3

Dependents: 0

Suggesters: 0

Stars: 1

Open Issues: 0

v1.0.2 2026-06-19 06:53 UTC

This package is auto-updated.

Last update: 2026-06-20 13:17:13 UTC


README

Turn your Laravel API routes into a complete, importable Postman Collection โ€” docs, examples, tests, environments, and one-command push โ€” with zero manual annotations.

PHP 8.2+ Laravel 10 | 11 | 12 Tests PHPStan Code style License

๐Ÿ“– Documentation ย ยทย  Packagist ย ยทย  Issues

php artisan postman:sync

That's it. The package scans every API route, reads your controllers and FormRequest classes, and writes a Postman Collection v2.1 (with embedded docs and test scripts), per-stage environment files, and an OpenAPI document โ€” then, with --push, syncs it straight to your Postman workspace.

๐Ÿ“– Full documentation, guides and examples: postman-sync.bhaveshdev.in

Why

Keeping a Postman collection in step with a growing API is tedious and always out of date. This package makes the collection a build artifact: re-run one command and your routes, request bodies, auth, examples, docs, and tests regenerate deterministically. Add 10 new endpoints and --push appends just those โ€” without clobbering the manual edits your team made in Postman.

Features

  • ๐Ÿ”Ž Automatic route scanning โ€” every GET/POST/PUT/PATCH/DELETE, apiResource, and resource; derives version, group, controller, and middleware.
  • ๐Ÿงฌ Reflection-based analysis โ€” finds each controller's FormRequest and reads its rules(); no annotations required.
  • ๐Ÿงพ Typed request bodies + examples โ€” required|email|min:8|in:โ€ฆ|confirmed|nullable|fileโ€ฆ mapped to types and realistic example values, including nested/wildcard keys.
  • ๐Ÿ” Auth detection โ€” auth:<guard> โ†’ Bearer {{guard_token}}; collection-level auth with per-request overrides; public routes set noauth.
  • ๐Ÿ“ฆ Postman Collection v2.1 โ€” folder-grouped, fully variable-driven ({{base_url}}, :id path vars) โ€” no hardcoded hosts or secrets.
  • ๐Ÿ“š Docs in Postman โ€” endpoint summary, field table, and example responses embedded in each request's Docs tab (plus folder/collection descriptions).
  • ๐Ÿงช Generated test scripts โ€” status / response-time / JSON assertions, login-token capture into the environment, and validation/CRUD stubs.
  • ๐ŸŒฑ Environment files โ€” one per stage (local/staging/production) with secret-typed guard tokens.
  • ๐Ÿ“œ OpenAPI 3.0.3 โ€” openapi.json generated alongside.
  • ๐Ÿš€ One-command push โ€” --push uploads to the Postman API with incremental merge (append new, regenerate changed, preserve unchanged + manual edits) or --fresh full replace.
  • ๐Ÿ›Ÿ Never breaks your build โ€” closures, missing FormRequests, and bad controllers degrade gracefully with warnings; exits 0.

Requirements

PHP 8.2+
Laravel 10, 11, or 12

Installation

composer require bhaveshsoni26/laravel-postman-sync

The service provider auto-registers via package discovery. Publish the config:

php artisan vendor:publish --tag=postman-sync-config

Not on Packagist yet? Install from a local path repository โ€” see INSTALLATION.md for the one-time repositories setup.

Quick start

# Generate collection + environments + openapi.json (into storage/app/postman/)
php artisan postman:sync
+---------------------+-------+
| Metric              | Value |
+---------------------+-------+
| Routes Found        | 164   |
| Requests Generated  | 164   |
| Warnings            | 0     |
| Files Written       | 5     |
+---------------------+-------+
Synced Successfully

Import storage/app/postman/collection.json and an environment file into Postman, fill in the token variables, and send.

What it generates

storage/app/postman/
โ”œโ”€โ”€ collection.json                   # Postman Collection v2.1 (docs + test scripts embedded)
โ”œโ”€โ”€ openapi.json                      # OpenAPI 3.0.3
โ”œโ”€โ”€ local.postman_environment.json    # one per configured stage
โ”œโ”€โ”€ staging.postman_environment.json
โ””โ”€โ”€ production.postman_environment.json

Command reference

Command Result
postman:sync collection + environments + openapi (default)
postman:sync --only=collection only collection.json
postman:sync --only=environment only the environment file(s)
postman:sync --only=openapi only openapi.json
postman:sync --docs-files also write standalone Markdown to <output>/docs/
postman:sync --output=build/postman custom output directory
postman:sync --push generate, then merge into the Postman collection
postman:sync --push --fresh full replace of the remote collection

Push to Postman

POSTMAN_API_KEY=PMAK-xxxx
POSTMAN_COLLECTION_ID=xxxx   # set to update an existing collection
POSTMAN_WORKSPACE_ID=xxxx    # optional, used when creating
php artisan postman:sync --push
# Pushed to Postman (merge): added 10, updated 2, unchanged 152, orphaned 0 [12345-abc]

Incremental merge appends new routes, regenerates changed ones, and leaves unchanged requests โ€” including manual edits to their docs/tests โ€” untouched. Use --fresh to overwrite the whole collection.

Getting your Postman credentials

You only need the API key to push. The collection ID and workspace ID are optional (see notes below).

1. API key โ€” POSTMAN_API_KEY (required)

  1. Sign in to Postman and open go.postman.co/settings/me/api-keys (or: click your avatar, top-right โ†’ Settings โ†’ API keys).
  2. Click Generate API Key, give it a name (e.g. laravel-postman-sync), and Generate.
  3. Copy the key โ€” it starts with PMAK- โ€” and put it in .env:
    POSTMAN_API_KEY=PMAK-xxxxxxxxxxxxxxxxxxxxxxxx

    Treat it like a password. You can only see it once; regenerate if you lose it.

2. Collection ID โ€” POSTMAN_COLLECTION_ID (optional)

Leave this empty the first time โ€” --push creates a new collection and prints its ID:

Pushed to Postman (create): added 484, ... [12345678-aaaa-bbbb-cccc-1234567890ab]

Copy that ID into .env so future pushes update the same collection instead of creating duplicates:

POSTMAN_COLLECTION_ID=12345678-aaaa-bbbb-cccc-1234567890ab

To target a collection that already exists, fetch its exact API uid (not the short id shown in the app) โ€” list them with your key:

curl -s -H "X-Api-Key: $POSTMAN_API_KEY" https://api.getpostman.com/collections | json_pp

Use the uid value from the response (looks like 12345678-...).

3. Workspace ID โ€” POSTMAN_WORKSPACE_ID (optional)

Only used when creating a new collection, to place it in a specific workspace. Omit it to use your default workspace.

  • From the app: open the workspace, then look at the browser URL: https://go.postman.co/workspace/My-Team~<workspace-id>/... โ€” the ID is the part after the ~.
  • Via the API: list your workspaces and copy the id:
    curl -s -H "X-Api-Key: $POSTMAN_API_KEY" https://api.getpostman.com/workspaces | json_pp
POSTMAN_WORKSPACE_ID=abcdef12-3456-7890-abcd-ef1234567890

After editing .env, run php artisan config:clear so Laravel picks up the new values, then php artisan postman:sync --push.

Configuration

Key options in config/postman-sync.php:

'api_prefix'      => 'api',                 // routes to scan
'output_path'     => storage_path('app/postman'),
'base_url'        => env('APP_URL').'/api', // seeds {{base_url}}
'default_guard'   => 'sanctum',             // collection-level auth
'guard_tokens'    => [],                    // guard => token var override
'environments'    => ['local', 'staging', 'production'],
'generate_tests'  => true,
'capture_login_token' => true,
'postman' => [
    'api_key'       => env('POSTMAN_API_KEY'),
    'collection_id' => env('POSTMAN_COLLECTION_ID'),
    'sync_mode'     => 'merge',             // merge | replace
    'prune_orphans' => false,
],

Full configuration reference and a multi-guard (CRM-style) example are in INSTALLATION.md.

How it works

RouteScanner โ”€โ–บ RequestAssembler โ”€โ–บ CollectionBuilder โ”€โ”
   (ControllerScanner + Validation/Auth/Example/        โ”œโ”€โ–บ collection.json
    Response extractors)                                 โ”‚   environment.json
                                โ”€โ–บ EnvironmentGenerator โ”€โ”ค   openapi.json
                                โ”€โ–บ MarkdownGenerator โ”€โ”€โ”€โ”€โ”ค   (+ docs in request descriptions)
                                โ”€โ–บ OpenApiGenerator โ”€โ”€โ”€โ”€โ”€โ”ค
                                โ”€โ–บ TestScriptBuilder โ”€โ”€โ”€โ”€โ”˜
                                โ”€โ–บ PostmanSyncService โ”€โ–บ CollectionMerger โ”€โ–บ PostmanApiClient  (--push)

A one-directional pipeline of immutable DTOs; each stage is interface-backed and independently tested.

Testing

composer test     # Pest
composer stan     # PHPStan level max
composer lint     # Pint --test

All Postman API calls go through Laravel's Http facade and are mocked with Http::fake() โ€” the test suite needs no real API key or network.

Contributing

Issues and PRs welcome. Please run composer test && composer stan && composer lint before submitting. New code uses declare(strict_types=1) and Sorbet-style full type hints; tests are written in Pest.

License

MIT.