- Web routes (
/admin/cotizaciones/*) — session-authenticated, return HTML views or redirects. - API routes (
/api/v1/quotes/*) — Sanctum Bearer token, return JSON.
All web routes require the
auth + verified middleware. All API routes require a valid Sanctum Bearer token and are throttled at 30 requests per minute.Web routes
List quotes
GET /admin/cotizaciones
Returns a paginated HTML view of all quotes, 15 per page, ordered newest first.
Filter by quote status. Accepted values:
draft, sent, accepted, rejected, expired.Full-text search across
client_name, client_email, and reference (case-insensitive LIKE match).cURL
This route returns an HTML view, not JSON. Use it as a browser navigation target, not a data API.
Show quote
GET /admin/cotizaciones/{quote}
Loads a single quote with its line items (and their associated blocks) and replies (sorted newest first).
The quote’s primary key.
cURL
Update quote status
PATCH /admin/cotizaciones/{quote}/status
Updates the status field of the quote.
The quote’s primary key.
New status value. Accepted:
draft, sent, accepted, rejected, expired.cURL
Reply to quote (schedule meeting + send email)
POST /admin/cotizaciones/{quote}/reply
Schedules a virtual meeting, saves a QuoteReply record, generates a PDF of the quote, and emails the client with the PDF attached.
The quote’s primary key.
The meeting date and time in any format parseable by PHP’s
DateTime. Recommend ISO 8601: YYYY-MM-DD HH:MM.
This value is stored verbatim in quote_replies.sent_at.The meeting message saved on the
QuoteReply and included in the email is formatted as:
Cita Virtual en GoogleMeet: DD/MM/YYYY HH:MM- Validates
meeting_dateas a required date. - Creates a
QuoteReplyrow withquote_id, the formattedmessage, andsent_at = meeting_date. - Generates a fresh PDF from the quote’s items.
- Saves the PDF to
storage/app/public/quotes/{reference}.pdf. - Dispatches
QuoteReplyMailtoquote.client_emailwith the PDF attached. - Redirects to
admin.quotes.showwith asuccessflash.
cURL
Download quote PDF
GET /admin/cotizaciones/{quote}/pdf
Generates and streams the PDF for an existing quote as a file download.
The quote’s primary key.
Content-Type: application/pdfContent-Disposition: attachment; filename="cotizacion-{reference}.pdf"
cURL
API routes (Bearer token)
All routes below are prefixed/api/v1/ and require Authorization: Bearer <token>.
Get statistics
GET /api/v1/quotes/statistics
Returns aggregate counts and monetary totals across all quotes. Results are cached for one hour per calendar month.
cURL
Total number of quotes in the database across all time.
Number of quotes with status
sent.Number of quotes with status
accepted.Number of quotes created today (server’s local date).
Number of quotes created since the start of the current calendar month.
Number of quotes created since the start of the current year.
Sum of the
total column across all quotes.Average of the
total column across all quotes. 0 when there are no quotes.Top 5 clients by quote count, each with
client_email, client_name, count, and total.Response example
Get recent quotes
GET /api/v1/quotes/recent
Returns the most recently created quotes, each including their line items.
Maximum number of quotes to return. No upper bound is enforced by the server.
cURL
Always
true on a successful response.Array of quote objects, ordered newest first, with related
items eager-loaded.Response example
Duplicate quote
POST /api/v1/quotes/{id}/duplicate
Creates a copy of a quote. The duplicate gets a fresh auto-generated reference, its status is reset to draft, and sent_at and pdf_path are cleared. No line items are copied in the current implementation — the top-level quote fields are replicated.
The primary key of the quote to duplicate.
cURL
Always
true on a successful duplication.Auto-generated reference for the duplicated quote (e.g.
COT-67A1B2C3D4E5F).Confirmation message:
"Cotización duplicada exitosamente".Response example
Export quotes to CSV
GET /api/v1/quotes/export
Exports quotes to a CSV file. Supports optional date range and status filters. Results are ordered newest first.
Filter to quotes created on or after this date. Format:
YYYY-MM-DD.Filter to quotes created on or before this date. Must be
>= start_date. Format: YYYY-MM-DD.Filter by quote status. Accepted:
draft, sent, accepted, rejected, expired.Referencia, Cliente, Email, Empresa, Total, IVA, Subtotal, Horas, Estado, Fecha
cURL
Content-Type: text/csvContent-Disposition: attachment; filename="quotes_export_{YYYY-MM-DD_HH-MM-SS}.csv"
422:
Quote model fields reference
| Field | Type | Notes |
|---|---|---|
id | integer | Auto-increment primary key |
reference | string | Auto-generated on creation: COT- + uppercased uniqid() |
client_name | string | Required |
client_email | string | Required |
client_company | string|null | Optional |
client_phone | string|null | Optional |
additional_requirements | string|null | Free-text notes |
data | array (JSON) | Full raw payload from the quote builder |
cita | array (JSON) | Appointment data |
subtotal | decimal:2 | Pre-tax total |
tax | decimal:2 | Tax amount |
total | decimal:2 | Grand total |
total_hours | integer | Aggregate estimated hours |
status | string | draft / sent / accepted / rejected / expired |
sent_at | datetime|null | Populated on submission |
pdf_path | string|null | Relative path in storage/app/public/ |