Quote blocks are the service line items that make up a quote. They are grouped into categories. These endpoints are public — no authentication required.
All endpoints in this page are rate limited to 60 requests per minute .
GET /api/quote-blocks
Returns all active categories with their active blocks, ordered by order ascending.
Request
No parameters required.
curl https://your-domain.com/api/quote-blocks
Response
Always true on a successful response.
Ordered array of active category objects. Show Category object properties
Unique category identifier.
Display name of the category.
Optional description of what this category covers.
Whether the category should be shown expanded in the UI. Always true in this response.
Ordered array of active quote blocks belonging to this category. Show Block object properties
Display name of the block.
Description of the service the block represents.
Block type (e.g., generic, hourly, fixed).
ID of the parent category.
Base price as a float with two decimal places.
Default estimated hours for this block.
Additional configuration for the block. Returns an empty object {} when no config is set.
Sort order of the block within its category.
Examples
curl https://your-domain.com/api/quote-blocks
{
"success" : true ,
"categories" : [
{
"id" : 1 ,
"name" : "Web Development" ,
"description" : "Frontend and backend web services" ,
"expanded" : true ,
"blocks" : [
{
"id" : 10 ,
"name" : "Landing Page" ,
"description" : "Single-page marketing site" ,
"type" : "fixed" ,
"category_id" : 1 ,
"base_price" : 1500.00 ,
"default_hours" : 40 ,
"config" : {},
"order" : 1
}
]
}
]
}
GET /api/quote-blocks/category/
Returns all active blocks belonging to a specific category, ordered by order ascending.
Path parameters
The ID of the category whose blocks you want to retrieve.
Request
curl https://your-domain.com/api/quote-blocks/category/1
Response
Returns a JSON array of QuoteBlock model objects. Each object contains the full model attributes.
[
{
"id" : 10 ,
"name" : "Landing Page" ,
"description" : "Single-page marketing site" ,
"type" : "fixed" ,
"category_id" : 1 ,
"base_price" : "1500.00" ,
"default_hours" : 40 ,
"config" : null ,
"is_active" : true ,
"order" : 1 ,
"created_at" : "2024-01-01T00:00:00.000000Z" ,
"updated_at" : "2024-01-01T00:00:00.000000Z"
}
]
If the category does not exist, this endpoint returns an empty array rather than a 404 error.
POST /api/quote-blocks/calculate
Calculates the price for a specific block given its quantity and type-specific parameters. The pricing logic varies by block type and uses the block’s formula field when present; otherwise it applies type-specific rules.
Request body
The ID of the QuoteBlock to price. Must exist in the quote_blocks table.
Number of units. Minimum 1.
Type-specific parameters used by the pricing formula. Contents vary by block type: Show Parameters by block type
course blocks:
participants (integer) — number of attendees; minimum 10
modality (string) — "online" or "onsite"
software_module blocks:
complexity (string) — "low", "medium", or "high"
estimatedHours (integer) — minimum 1
requiresIntegration (boolean) — adds integration hours from the block config
audit blocks:
scope (string) — "basic", "standard", or "comprehensive"
systems (integer) — number of systems; minimum 1
generic and other types: no additional parameters required; price = base_price × quantity.
Response
Calculated total price as a float.
Price formatted as a string: "$1,234.56 MXN".
Price per unit (price / quantity).
Confirmation: "Precio calculado exitosamente".
Examples
curl --request POST \
https://your-domain.com/api/quote-blocks/calculate \
--header "Content-Type: application/json" \
--data '{
"block_id": 5,
"quantity": 2,
"parameters": {
"complexity": "high",
"estimatedHours": 80,
"requiresIntegration": true
}
}'
{
"success" : true ,
"price" : 95000.00 ,
"formatted_price" : "$95,000.00 MXN" ,
"unit_price" : 47500.00 ,
"message" : "Precio calculado exitosamente"
}
{
"success" : false ,
"errors" : {
"block_id" : [ "The block id field is required." ],
"quantity" : [ "The quantity field must be at least 1." ]
}
}