Si llevas tiempo haciendo APIs en Laravel, ya sabes el dolor: documentación desactualizada, endpoints que cambian, validaciones que no se reflejan en Swagger, etc. Scramble viene a quitarte ese peso de encima generando documentación OpenAPI 3.1 a partir de tu código y convenciones de Laravel (FormRequests, Resources, rutas, modelos…).
En este artículo vamos a montarlo desde cero y dejarlo fino: instalación, publicación de configuración, seguridad de acceso, y ejemplos reales con código.
1) ¿Qué es Scramble y qué te aporta?
Scramble es un generador moderno de documentación OpenAPI para Laravel que:
Te crea el UI de docs y el JSON OpenAPI
Detecta rutas y operaciones automáticamente (por defecto, rutas bajo api/*)
Entiende muchas cosas típicas de Laravel: validaciones en FormRequest, Resources, paginación, enums, etc.
Cuando lo instalas, expone dos rutas:
/docs/api → la web para ver la doc
/docs/api.json → el JSON OpenAPI
Y detalle importante: por defecto esas rutas solo están accesibles en local
2) Requisitos
Según la doc oficial:
PHP 8.1+
Laravel 10+
3) Instalación
En tu proyecto:
composer require dedoc/scramble
Eso ya registra las rutas /docs/api y /docs/api.json.
Prueba en local:
https://tu-app.test/docs/api
4) Publicar el archivo de configuración
Scramble funciona “out of the box”, pero en cuanto quieras controlar qué documenta y cómo se ve, vas a querer el config.
php artisan vendor:publish --provider="Dedoc\Scramble\ScrambleServiceProvider" --tag="scramble-config"
Esto te crea config/scramble.php y desde ahí ajustas el comportamiento.
5) Entendiendo config/scramble.php (lo importante)
5.1 api_path: qué rutas entran en la doc
Por defecto, Scramble documenta rutas bajo api (o sea api/*). Si tu API vive en api/v1, ajusta:
// config/scramble.php
return [
'api_path' => 'api/v1',
];
Scramble lo menciona tal cual: por defecto agrega rutas que empiezan por api, y puedes cambiarlo con scramble.api_path
5.2 api_domain: si tu API va por subdominio
Si tienes algo tipo api.tusitio.com, puedes fijarlo:
return [
'api_domain' => 'api.tusitio.com',
];
Por defecto es null (usa el dominio actual).
5.3 info: lo que se ve en el “home” de /docs/api
La descripción soporta Markdown:
return [
'info' => [
'version' => env('API_VERSION', '0.0.1'),
'description' => <<<MD
Bienvenido a la documentación de mi API.
- Autenticación: Bearer Token
- Soporte: soporte@tusitio.com
MD,
],
];
La doc indica que scramble.info.description se renderiza en /docs/api y soporta Markdown.
6) Seguridad: permitir acceso a /docs/api en producción (Gate)
Por defecto, solo local puede ver las docs. Si quieres habilitarlo en staging/prod, defines el Gate viewApiDocs.
// app/Providers/AppServiceProvider.php
use App\Models\User;
use Illuminate\Support\Facades\Gate;
public function boot(): void
{
Gate::define('viewApiDocs', function (User $user) {
return in_array($user->email, [
'admin@app.com',
]);
});
}
Esto hace que, fuera de local, solo quien pase el gate pueda acceder.
7) Control fino: decidir tú qué rutas se documentan
Además del api_path, puedes filtrar rutas con una función “resolver” en un Service Provider usando Scramble::configure()->routes(...).
Ejemplo: documentar solo api/* y excluir healthchecks:
// app/Providers/AppServiceProvider.php
use Dedoc\Scramble\Scramble;
use Illuminate\Routing\Route;
use Illuminate\Support\Str;
public function boot(): void
{
Scramble::configure()
->routes(function (Route $route) {
if (! Str::startsWith($route->uri, 'api/')) {
return false;
}
// Excluye endpoints tipo /api/health
return $route->uri !== 'api/health';
});
}8) Ejemplo completo: endpoint REST con FormRequest + Resource
Vamos a montar un endpoint típico de “Users” para que veas cómo Scramble saca jugo de tus convenciones.
8.1 Ruta
// routes/api.php
use App\Http\Controllers\Api\UserController;
use Illuminate\Support\Facades\Route;
Route::get('/users', [UserController::class, 'index']);
Route::post('/users', [UserController::class, 'store']);
Route::get('/users/{user}', [UserController::class, 'show']);
8.2 FormRequest con validaciones (Scramble lo aprovecha)
// app/Http/Requests/StoreUserRequest.php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class StoreUserRequest extends FormRequest
{
public function rules(): array
{
return [
'name' => ['required', 'string', 'min:2'],
'email' => ['required', 'email', 'unique:users,email'],
];
}
}
8.3 API Resource para respuesta consistente
// app/Http/Resources/UserResource.php
namespace App\Http\Resources;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
/** @mixin \App\Models\User */
class UserResource extends JsonResource
{
public function toArray(Request $request): array
{
return [
'id' => $this->id,
'name' => $this->name,
'email' => $this->email,
];
}
}
8.4 Controller
// app/Http/Controllers/Api/UserController.php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Http\Requests\StoreUserRequest;
use App\Http\Resources\UserResource;
use App\Models\User;
use Illuminate\Http\Resources\Json\ResourceCollection;
class UserController extends Controller
{
public function index(): ResourceCollection
{
return UserResource::collection(
User::query()->paginate(15)
);
}
public function store(StoreUserRequest $request): UserResource
{
$user = User::query()->create($request->validated());
return new UserResource($user);
}
public function show(User $user): UserResource
{
return new UserResource($user);
}
}
Con esto, Scramble suele ser capaz de:
- Detectar parámetros de path (
{user}) - Detectar estructura de respuesta (por el Resource)
- Detectar validaciones del request (por el FormRequest)
- Detectar paginación (cuando devuelves
paginate(), según la evolución reciente del paquete)
9) Documentar autenticación (Bearer) para toda la API
OpenAPI necesita que declares los esquemas de seguridad. Scramble lo resuelve con document transformers.
Ejemplo: marcar toda la API como Bearer:
// app/Providers/AppServiceProvider.php
use Dedoc\Scramble\Scramble;
use Dedoc\Scramble\Support\Generator\OpenApi;
use Dedoc\Scramble\Support\Generator\SecurityScheme;
public function boot(): void
{
Scramble::configure()
->withDocumentTransformers(function (OpenApi $openApi) {
$openApi->secure(
SecurityScheme::http('bearer')
);
});
}
Esto está tal cual en la doc de autenticación de Scramble.
10) Resultado: revisa tu documentación
Arrancas local:
php artisan serve
Visitas:
http://localhost:8000/docs/api
http://localhost:8000/docs/api.json
Y deberías ver:
- Endpoints listados
- Esquemas de request/response
- Validaciones reflejadas
- Auth marcada (si aplicaste el transformer)
Conclusión (y consejo de senior a senior)
Scramble brilla cuando te apoyas en “Laravel bien hecho”:
- FormRequests para entrada
- Resources para salida
- Rutas limpias y REST
- Paginación estándar
Así la documentación sale sola… y lo mejor: tiende a mantenerse en sync con tu código.

