Web routes
Session-authenticated form-based endpoints at
/bloques/*. Return HTML views or redirects.API routes
Sanctum Bearer token endpoints at
/api/v1/admin/quote-blocks/*. Return JSON.Web routes require the
auth + verified middleware. API routes require a valid Sanctum Bearer token and are throttled at 30 requests per minute.Web routes
List blocks
GET /bloques
Returns an HTML view listing all categories (ordered by order) with their blocks (each category’s blocks ordered by order).
cURL
Create block form
GET /bloques/create
Returns the HTML form to create a new block. The form is pre-populated with all available categories.
cURL
Store block
POST /bloques
Validates and persists a new quote block. The block’s order is set to max(order) + 1 within the chosen category. is_active defaults to true if omitted.
Display name of the block. Maximum 255 characters.
ID of an existing row in
quote_block_categories. Must pass an exists check.Base price for the block. Must be numeric and
>= 0.Default estimated hours. Must be an integer
>= 0.Optional free-text description.
Whether the block is visible in the public builder. Treated as a boolean checkbox — the server calls
$request->boolean('is_active', true).Key/value pairs stored in the JSON
config column. Each item must have a key and a value.
Numeric values are cast to numbers; all others remain strings.cURL
/bloques with a success flash.
On validation failure: redirects back with errors and input preserved.
Edit block form
GET /bloques/{bloque}/edit
Returns the HTML edit form pre-populated with the block’s current values.
The block’s primary key. Laravel’s route model binding uses the
bloque parameter name.cURL
Update block
PUT /bloques/{bloque} or PATCH /bloques/{bloque}
Updates an existing block. Applies the same validation rules as store. order is not updated by this endpoint — use the reorder API route for that.
The block’s primary key.
Display name. Maximum 255 characters.
Must reference a valid
quote_block_categories.id.Must be numeric and
>= 0.Must be an integer
>= 0.Optional free-text description.
Active state.
Replaces the entire
config JSON column. Same shape as the store endpoint.cURL
/bloques with a success flash.
On validation failure: redirects back with errors and input preserved.
Delete block
DELETE /bloques/{bloque}
Permanently deletes the block.
The block’s primary key.
cURL
/bloques with a success flash.
Create category
POST /bloques/categorias
Creates a new block category. The category’s order is set to max(order) + 1 globally. is_active is always set to true on creation.
Category name. Must be unique across
quote_block_categories.name. Maximum 255 characters.Optional description. Maximum 500 characters.
Validation errors for this form are returned under the
category error bag (not the default bag), so they can be rendered separately from block form errors on the same page.cURL
/bloques with a success flash.
On validation failure: redirects back with category error bag errors and input preserved.
API routes (Bearer token)
All routes are prefixed/api/v1/admin/ and require Authorization: Bearer <token> with the auth:sanctum middleware.
List all blocks
GET /api/v1/admin/quote-blocks
Returns all quote blocks.
cURL
Create block
POST /api/v1/admin/quote-blocks
cURL
Get block
GET /api/v1/admin/quote-blocks/{id}
The block’s primary key.
cURL
Primary key.
Block display name.
Optional description.
Foreign key to
quote_block_categories.Base price (decimal:2).
Estimated hours.
Array of
{key: value} configuration pairs.Whether the block is visible in the builder.
Display sort order within the category.
ISO 8601 timestamp.
ISO 8601 timestamp.
Response example
Update block
PUT /api/v1/admin/quote-blocks/{id}
The block’s primary key.
cURL
Delete block
DELETE /api/v1/admin/quote-blocks/{id}
The block’s primary key.
cURL
Reorder blocks
POST /api/v1/admin/quote-blocks/reorder
Updates the order field for one or more blocks in a single request. Each block in the payload is updated individually via a targeted UPDATE query.
Array of reorder instructions. Every listed block is updated; unlisted blocks are untouched.
cURL
Always
true on success.Response
QuoteBlock model fields reference
| Field | Type | Notes |
|---|---|---|
id | integer | Auto-increment primary key |
name | string | Required, max 255 |
description | string|null | Optional |
category_id | integer | FK → quote_block_categories.id |
base_price | decimal:2 | Min 0 |
default_hours | integer | Min 0 |
config | array (JSON) | Stored as [{key: value}, ...] |
is_active | boolean | Filters visible blocks in the builder |
order | integer | Sort order within category |
QuoteBlockCategory model fields reference
| Field | Type | Notes |
|---|---|---|
id | integer | Auto-increment primary key |
name | string | Required, unique, max 255 |
description | string|null | Optional, max 500 |
icon | string|null | Display icon identifier |
color | string|null | Display color value |
order | integer | Global sort order |
is_active | boolean | Always true on creation via UI |