Documentation Index Fetch the complete documentation index at: https://mintlify.com/charlietyn/openapi-generator/llms.txt
Use this file to discover all available pages before exploring further.
This guide demonstrates practical scenarios for using the Laravel OpenAPI Generator in production environments.
Scenario 1: Generate Admin + Mobile Docs from CLI
Goal : Produce OpenAPI + Postman + Insomnia outputs only for admin and mobile APIs.
Setup
Define API types in config/openapi.php:
'api_types' => [
'admin' => [
'prefix' => 'admin' ,
'folder_name' => 'API Admin' ,
'enabled' => true ,
],
'mobile' => [
'prefix' => 'mobile' ,
'folder_name' => 'API Mobile' ,
'enabled' => true ,
],
'site' => [
'prefix' => 'api' ,
'folder_name' => 'API Public' ,
'enabled' => false , // Not included
],
],
Ensure the output directory is writable:
chmod -R 775 storage/app/public/openapi
Execution
Publish configuration
php artisan vendor:publish --tag=openapi-config
This creates config/openapi.php where you can customize API types, routes, and environments.
Run the generator
php artisan openapi:generate --all --api-type=admin --api-type=mobile
Expected output: 🚀 Generating OpenAPI Specification...
🔍 Filtering API types: admin, mobile
📋 Inspecting routes...
✅ Found 34 unique paths
💾 Writing OpenAPI specification...
✅ OpenAPI specification generated!
📄 File: storage/app/public/openapi/openapi-admin-mobile.json
📮 Generating Postman collection...
✅ Postman collection generated!
📄 File: storage/app/public/openapi/postman-admin-mobile.json
📋 Generating Postman environments...
├─ artisan: postman-env-artisan.json
├─ local: postman-env-local.json
└─ production: postman-env-production.json
🛏️ Generating Insomnia workspace...
✅ Insomnia workspace generated!
📄 File: storage/app/public/openapi/insomnia-admin-mobile.json
├─ Includes 3 environments (base + artisan + local + production)
├─ Minimal API Spec tab
└─ Automated tests included
✨ Generation complete! (--all mode)
Notes
Filenames include the filtered API type suffix (admin-mobile)
The generator validates that API types are enabled in config
Both Postman and Insomnia files include embedded environment variables
Common Mistakes
Using disabled or missing API types If you request an API type that’s disabled or not defined: php artisan openapi:generate --api-type=unknown
You’ll get an error: ❌ Unknown or disabled API types: unknown. Available types: admin, mobile
Solution : Check config/openapi.php and ensure the API type is defined and enabled.
Forgetting to publish config Without publishing config, the package uses defaults which may not match your route structure. Always publish config files: php artisan vendor:publish --tag=openapi-config
Goal : Allow internal consumers (mobile apps, frontend teams, partner APIs) to fetch documentation via HTTP routes.
Setup
Enable routes in config/openapi.php:
'routes' => [
'enabled' => true ,
'prefix' => 'documentation' ,
'middleware' => [], // Or ['auth:sanctum'] for protection
],
Execution
OpenAPI JSON
OpenAPI YAML
Filtered by API Type
Postman Collection
curl http://localhost:8000/documentation/openapi.json
Returns the complete OpenAPI 3.0.3 specification. curl http://localhost:8000/documentation/openapi.yaml
Returns the same specification in YAML format. curl "http://localhost:8000/documentation/openapi.json?api_type=admin,mobile"
Returns only routes matching admin or mobile API types. curl "http://localhost:8000/documentation/postman?api_type=mobile&environment=production"
Returns a Postman collection filtered to mobile routes with production environment variables.
Notes
HTTP endpoints use the same generation logic as the CLI
Documentation is generated on-demand (not served from static files)
Query parameters apply the same filters as CLI flags
Common Mistakes
Middleware blocking access If you add authentication middleware: 'middleware' => [ 'auth:sanctum' ],
Unauthenticated requests return 401: curl http://localhost:8000/documentation/openapi.json
# {"message":"Unauthenticated."}
Solution : Either remove the middleware for public docs or include authentication headers:curl -H "Authorization: Bearer YOUR_TOKEN" \
http://localhost:8000/documentation/openapi.json
Invalid format parameter The {format} parameter only accepts: json, yaml, yml, postman, insomnia. curl http://localhost:8000/documentation/openapi.xml
# 404 Not Found
Scenario 3: Custom Endpoint Documentation
Goal : Document a non-CRUD endpoint like api-apps.rotate with custom descriptions and request fields.
Setup
Add custom endpoint configuration in config/openapi-docs.php:
return [
'custom_endpoints' => [
'api-apps.rotate' => [
'summary' => 'Rotate API Key' ,
'description' => 'Generates a new API key for the application and revokes the old one.' ,
'request_fields' => [
'reason' => 'Optional reason for key rotation (auditing purposes)' ,
],
'response_description' => 'Returns the new API key, revocation timestamp, and affected scopes.' ,
],
'users.export' => [
'summary' => 'Export Users' ,
'description' => 'Generates an export file of users matching the specified filters.' ,
'request_fields' => [
'format' => 'Export format: csv, xlsx, or json' ,
'filters' => 'Array of filter conditions (e.g., {"status": "active"})' ,
'columns' => 'Array of column names to include' ,
],
'response_description' => 'Returns download URL and file metadata.' ,
],
],
];
Execution
Define route with name
Ensure your route has a name matching the custom endpoint key: Route :: post ( 'api-apps/{app}/rotate' , [ ApiAppController :: class , 'rotate' ])
-> name ( 'api-apps.rotate' );
Route :: post ( 'users/export' , [ UserController :: class , 'export' ])
-> name ( 'users.export' );
Regenerate documentation
php artisan openapi:generate
The generator matches route names to custom endpoint keys and applies the custom documentation.
Verify in OpenAPI output
Open storage/app/public/openapi/openapi.json and find your endpoint: {
"/api-apps/{app}/rotate" : {
"post" : {
"summary" : "Rotate API Key" ,
"description" : "Generates a new API key for the application and revokes the old one." ,
"requestBody" : {
"content" : {
"application/json" : {
"schema" : {
"properties" : {
"reason" : {
"type" : "string" ,
"description" : "Optional reason for key rotation (auditing purposes)"
}
}
}
}
}
}
}
}
}
Notes
Use the entity.action pattern for keys
Custom endpoints override template-generated documentation
request_fields are merged with FormRequest validation rules
Common Mistakes
Key doesn’t match route name If you use a key that doesn’t match the route name: 'custom_endpoints' => [
'apps.rotate' => [ ... ], // Route is named 'api-apps.rotate'
],
The custom documentation won’t be applied. Always use the exact route name: php artisan route:list --name=rotate
# api-apps.rotate | POST | api-apps/{app}/rotate
Scenario 4: Template-Driven CRUD Documentation
Goal : Standardize list/show/create/update/delete descriptions using JSON templates to avoid repetitive manual documentation.
Setup
Publish templates
php artisan vendor:publish --tag=openapi-templates
This creates:
resources/openapi/templates/generic/list.json
resources/openapi/templates/generic/show.json
resources/openapi/templates/generic/create.json
resources/openapi/templates/generic/update.json
resources/openapi/templates/generic/delete.json
Enable template system
In config/openapi-templates.php: return [
'enabled' => true ,
'generic_templates' => [
'list' => 'list.json' ,
'show' => 'show.json' ,
'create' => 'create.json' ,
'update' => 'update.json' ,
'delete' => 'delete.json' ,
],
];
Customize templates
Edit resources/openapi/templates/generic/list.json: {
"summary" : "List {{entity_plural}}" ,
"description" : "Retrieve a paginated list of {{entity_plural}} with optional filtering and sorting." ,
"parameters" : [
{
"name" : "page" ,
"in" : "query" ,
"schema" : { "type" : "integer" , "default" : 1 },
"description" : "Page number"
},
{
"name" : "per_page" ,
"in" : "query" ,
"schema" : { "type" : "integer" , "default" : 15 },
"description" : "Items per page"
},
{
"name" : "sort" ,
"in" : "query" ,
"schema" : { "type" : "string" },
"description" : "Sort field and direction (e.g., 'created_at:desc')"
}
]
}
Execution
Generate documentation:
php artisan openapi:generate
The generator applies templates to all CRUD routes:
GET /users → uses list.json
GET /users/{id} → uses show.json
POST /users → uses create.json
PUT /users/{id} → uses update.json
DELETE /users/{id} → uses delete.json
Placeholders like {{entity_plural}} are replaced with users, {{entity_singular}} with user.
Notes
Templates reduce repetitive documentation
The generator falls back to metadata extraction when templates are disabled
Custom endpoint documentation overrides template output
Common Mistakes
JSON templates not found If template files are missing or paths are wrong: ❌ Failed to load template: resources/openapi/templates/generic/list.json
Solution : Verify template paths in config/openapi-templates.php match actual file locations.
Invalid JSON syntax Invalid JSON in templates causes parsing errors: {
"summary" : "List {{entity_plural}}" , // Missing closing brace
Solution : Validate JSON using jsonlint.com or your IDE.
Scenario 5: Generate Postman Environments
Goal : Export Postman environments for local development, staging, and production to use in API testing.
Setup
Define environments in config/openapi.php:
'environments' => [
'base' => [
'app_name' => env ( 'APP_NAME' , 'Laravel API' ),
'app_url' => env ( 'APP_URL' , 'http://localhost:8000' ),
],
'sub_environments' => [
'artisan' => [
'app_url' => 'http://localhost:8000' ,
],
'local' => [
'app_url' => 'http://localhost:8000' ,
],
'production' => [
'app_url' => 'https://api.example.com' ,
],
],
'tracking_variables' => [
'api_token' => '' ,
'device_id' => '' ,
'user_id' => '' ,
],
],
Execution
php artisan openapi:generate --with-postman
Creates:
postman-all.json - Main collection
postman-env-artisan.json
postman-env-local.json
postman-env-production.json
php artisan openapi:generate --with-postman --environment=production
Still generates all three environment files, but the main collection embeds production variables.
Import to Postman
Import collection
Open Postman
Click File > Import
Select postman-all.json
Import environments
Click Environments in left sidebar
Click Import
Select all postman-env-*.json files
Select environment
Click the environment dropdown (top right)
Select artisan, local, or production
All requests now use that environment’s base URL and variables
Notes
The environment generator merges base + tracking variables into each sub-environment
Tracking variables appear in all environments with empty default values
You can set actual token values in Postman’s environment editor
Common Mistakes
Defining tracking variables in sub-environments Don’t repeat tracking variables in each sub-environment: // ❌ Wrong
'sub_environments' => [
'local' => [
'app_url' => 'http://localhost:8000' ,
'api_token' => '' , // Don't do this
],
'production' => [
'app_url' => 'https://api.example.com' ,
'api_token' => '' , // Don't do this
],
],
// ✅ Correct
'tracking_variables' => [
'api_token' => '' , // Define once here
],
Tracking variables are automatically merged into all sub-environments.
Scenario 6: CI/CD Pipeline Integration
Goal : Automatically generate and publish documentation on every deployment.
GitHub Actions Example
name : Generate API Documentation
on :
push :
branches : [ main ]
pull_request :
branches : [ main ]
jobs :
docs :
runs-on : ubuntu-latest
steps :
- uses : actions/checkout@v3
- name : Setup PHP
uses : shivammathur/setup-php@v2
with :
php-version : '8.2'
- name : Install dependencies
run : composer install --no-dev --optimize-autoloader
- name : Generate documentation
run : |
php artisan openapi:generate --all --no-cache
- name : Upload to S3
uses : jakejarvis/s3-sync-action@master
with :
args : --acl public-read --follow-symlinks
env :
AWS_S3_BUCKET : ${{ secrets.AWS_S3_BUCKET }}
AWS_ACCESS_KEY_ID : ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY : ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_REGION : 'us-east-1'
SOURCE_DIR : 'storage/app/public/openapi'
DEST_DIR : 'docs/api'
GitLab CI Example
generate-docs :
stage : deploy
image : php:8.2-cli
before_script :
- curl -sS https://getcomposer.org/installer | php
- php composer.phar install --no-dev --optimize-autoloader
script :
- php artisan openapi:generate --all --no-cache
- aws s3 sync storage/app/public/openapi s3://your-bucket/docs/api --acl public-read
only :
- main
Notes
Always use --no-cache in CI/CD to ensure fresh output
Consider using --all to generate all formats
Upload to S3, CDN, or documentation hosting platform
Scenario 7: Team Workflow for API Development
Goal : Establish a workflow where backend developers generate docs, and frontend/mobile teams consume them.
Workflow
Developer adds new endpoint
Backend developer creates a new route with FormRequest validation: Route :: post ( 'products' , [ ProductController :: class , 'store' ])
-> name ( 'products.store' );
class StoreProductRequest extends FormRequest
{
public function rules ()
{
return [
'name' => 'required|string|max:255' ,
'price' => 'required|numeric|min:0' ,
'category_id' => 'required|exists:categories,id' ,
];
}
}
Generate documentation locally
php artisan openapi:generate --with-postman
Developer reviews the generated docs to ensure accuracy.
Commit generated files
Add documentation files to version control: git add storage/app/public/openapi/
git commit -m "Add product creation endpoint"
git push origin feature/add-products
CI/CD publishes docs
On merge to main, CI pipeline generates and publishes docs to a shared location: https://docs.example.com/api/openapi.json
https://docs.example.com/api/postman-all.json
Frontend/mobile teams consume docs
Teams import the latest Postman collection or view the OpenAPI spec in Swagger UI.
Best Practices
Tips for teams:
Keep docs in version control : Commit generated files so teams can see changes in PRs
Automate generation : Run generation in CI/CD to ensure docs are always up-to-date
Use custom endpoints : Document complex actions that don’t fit CRUD templates
Review generated output : Check that FormRequest rules and model properties are accurately reflected
Next Steps
Edge Cases Learn how to handle config caching issues, concurrent generation, large route sets, and multi-tenant deployments.
API Reference Explore the programmatic API for advanced integration scenarios.