Quotes
Quotes in Naqood are lightweight invoices whose status is quote. They never hit the ledger until you convert them into a draft or sent invoice, so you can run a full CPQ flow without touching accounting. This guide focuses on how to list, create, and convert quotes through the public GraphQL API.
Prerequisites
- A Naqood API secret or OAuth-issued secret scoped to the target organization
- The organization
slugfor every request - A role with the Invoices permission set (quotes reuse the invoice endpoints)
Quote shape
Quotes return the same fields as Invoice objects. Key properties to know:
| Field | Type | Notes |
|---|---|---|
id | ID! | Stable identifier for follow-up mutations. |
number | Int! | Quote numbers live in the same sequence as invoices. |
status | String! | Always quote until you convert the document. |
contactId | ID! | Customer the quote is addressed to. |
contactDetails | String! | Serialized snapshot of bill-to information. |
date | Date! | Displayed on the PDF; does not affect ledgers. |
lineItems | [JSONObject!]! | Items being quoted (see Products & Services). |
currency | String! | Defaults to organization currency. Provide exchangeRate for FX quotes. |
subtotal / vat / total | String | Calculated using the same rules as invoices. |
createdAt / updatedAt | Timestamp! | Audit timestamps. |
Because quotes are not posted, the journalEntries and baseJournalEntry fields are empty until the quote becomes an invoice.
Fetch a single quote
Use the invoice query with the quote ID:
query Quote($quoteID: ID!) {
invoice(invoiceID: $quoteID) {
id
number
status
date
contact {
id
name
}
lineItems
subtotal
vat
total
}
}
List quotes with filters
query Quotes(
$slug: Slug!
$offset: Int
$limit: Int
$orderBy: OrderByInput
$filter: JSONObject
) {
organization(slug: $slug) {
invoices(
offset: $offset
limit: $limit
orderBy: $orderBy
filter: $filter
) {
count
entries {
id
number
status
date
total
contact {
id
name
}
}
}
}
}
Apply filter: { status: { equalTo: "quote" } } so the dataset only returns quotes. The standard operators (equalTo, greaterThan, in, and/or) are supported for date ranges, contacts, currencies, and more.
Create a quote
Call createInvoice and set status to quote:
mutation CreateQuote($input: CreateInvoiceInput!) {
createInvoice(input: $input) {
id
number
status
total
}
}
Required input fields:
| Field | Required | Notes |
|---|---|---|
slug | ✅ | Organization issuing the quote. |
contactId | ✅ | Customer to quote. |
contactDetails | ✅ | Serialized address block rendered on the PDF. |
date | ✅ | Reference date shown to the customer. |
paymentTermType / paymentTermDays | ✅ | Define the validity window displayed on the quote. |
bankAccountId | ✅ | Included on the PDF if the customer accepts the quote as-is. |
lineItems | ✅ | Array of line payloads with quantities, pricing, VAT, and accounts. |
status | ✅ | Set to quote. |
Optional fields let you attach logos/stamps, set currency, exchangeRate, customize the document title (hero heading), the header (subtitle beneath the title), and the comment body copy shown before the header.
Update or duplicate quotes
mutation UpdateQuote($input: UpdateInvoiceInput!) {
updateInvoice(input: $input) {
id
status
total
updatedAt
}
}
- Only quotes (and draft invoices) can be edited. Sent invoices become read-only.
- To copy a quote, fetch its data via the queries above and pass the same payload back to
createInvoicewithstatus: "quote". - When the customer accepts, call
updateInvoicewith the quoteidand setstatustodraft. From there you can either make final edits or send the invoice immediately.
Email a quote
mutation SendQuote($input: SendInvoiceToCustomerInput!) {
sendInvoiceToCustomer(input: $input)
}
Supply the quote id and optional recipient list. The PDF renderer uses the same template as invoices, but the document retains status = quote until you explicitly convert it.
Delete a quote
mutation DeleteQuote($quoteID: ID!) {
deleteInvoice(invoiceID: $quoteID)
}
Deleting a quote removes it permanently because no ledger entries exist yet. If you mistakenly deleted a sent invoice, the mutation would void it instead.