Building a MonetizeNow quote
The individual tools describe their own mechanics well — required fields, id prefixes, which parameters belong on a create versus an update. Read them; this skill deliberately does not restate them, because a second copy of a field list is a copy that goes stale.
What the tool descriptions cannot tell you is the order, the defaults, and the handful of judgment calls that decide whether the resulting quote is structurally correct.
Order of operations
Resolve the account first. A quote is created against an account, so an ambiguous account name has to be settled before anything is written. See
monetizenow-data-retrieval.Create the quote. Apply the defaults the tool documents and ask only about what the request actually leaves open.
Create and update express the span differently — one takes a length, the other an end date — so read the description of whichever you are calling instead of carrying fields across. Converting a length into an end date is not arithmetic you should do from memory: span dates are inclusive, and adding months clamps at short months. The tool description gives the exact rule and a worked example; follow it rather than reasoning it out.
One term does not behave like the others: auto-renew is ignored on create. The platform takes it from the tenant's quote settings, so a value passed here is silently dropped. If the user asked for a specific auto-renew setting, read it off the returned quote and follow up with an update when it differs. This is the one default worth verifying every time.
Add the quote offerings, one call per offering. Ramps are a special case; see below.
Searching offerings by name or attribute returns only
ACTIVEones unless you say otherwise, which is what you want while quoting — an inactive offering is not sellable. Two consequences: a name that finds nothing may exist in another state, and a search targeting one specific offering by id is not filtered this way, so it can return an inactive one. Check the status before building on a result you reached by id.Price them. Pricing is its own ordered procedure — see
monetizenow-pricing-strategy. Do not reach for a discount just because it is the quickest way to move a total.Verify by retrieving the finished quote and reading its actual state. Describe what the quote is, not what you were trying to make it be — if a step did not land, that belongs in the summary. Auto-renew above is the concrete case: the create call reports success while quietly substituting the tenant's value, so only the returned quote tells you what was set.
Signal the redirect once, after the quote is successfully created, so the user can navigate to it. It is for newly created entities only, not for updates.
Defaults and judgment calls
Do not invent a start date to make a term land on a round number. Leaving it unset starts the contract today, which the tool description covers.
Exclude optional products the user did not mention. Offering products are flagged mandatory or
optional through offeringProducts[*].isMandatory. When quoting, an optional product the user
never brought up should be left off — adding it silently inflates the quote.
This is worth holding carefully, because the neighbouring rule is the exact opposite: creating a rate requires a pricing configuration for every product on the offering, optional ones included. Quoting excludes unmentioned optional products; rate creation prices all of them. The two rules sit one tool apart and are easy to transpose.
Ramps are groups, not repeated offerings
Any multi-period or ramped offering has to be built as a quote offering group: one root offering plus any number of ramp offerings that point back at it through their schedule. Every offering in the group keeps the same billing frequency.
Creating a standalone offering per period instead is not a stylistic variation — it is a fundamental design error. The periods end up unrelated, so the platform cannot treat them as one commercial arrangement, and downstream amendment and billing behavior is wrong even though the quote may total correctly.
The create_quote_offering tool description carries the exact construction rules — which field
identifies the root, which is mandatory on a ramp, what the ramp's span defaults to. Follow it.
Recognizing a ramp group when reading
Construction is documented; reading is not, and an agent can build a group correctly and still misread one. When you retrieve a quote, its offerings arrive as a flat list. To reconstruct the groups: an offering carrying a parent reference in its schedule is a ramp, and the offering it points at is the root. Offerings with no parent reference are roots — either of a group or standalone.
So a quote showing three offerings may be one root with two ramps, three independent offerings, or a root-plus-ramp alongside a standalone. Report the structure, not the count. "Three offerings" is misleading when the answer is "one product ramping across three years".
What cannot be done
Some things a quote shows are not writable by any tool — quote contacts are the case you will hit,
and update_quote says so directly. When you meet one, say plainly that it is not something you
can do. Do not offer a manual workaround or a path outside the platform: that reads as a
capability, and it is not one.
Quotes sit on contracts
A quote is not the whole story. Contracts are retrievable in their own right, and a retrieved contract carries every quote on it — the original plus each amendment and renewal — along with its renewal terms and whether it has been renewed.
That makes the contract the right object for any question about history or the current shape of a customer's commitment: what changed at the last amendment, what renews and when, which quote is live. Reconstructing that by searching quotes account-by-account gets you an unordered pile with no indication of which superseded which.
So when a request says "extend", "amend", "renew", or asks what the customer is currently on, start
from the contract rather than the newest quote you can find. To get there, call
monetizenow_search_objects with object_type set to "contract" — not from the account.
Contract, subscription, or quote?
Three objects describe the same customer from different angles, and picking the wrong one is the usual reason an answer comes out stale or incomplete:
- The quote is what was proposed. Useful for what was agreed at a point in time.
- The contract is the commitment, and carries every quote on it. Useful for history — what changed, when, and what renews.
- The subscription is what is actually running and being billed right now. Useful for the present state.
"What is this customer on?" is a subscription question. "What changed at the last amendment?" is a contract question. Answering either from the newest quote you can find tends to be wrong, because a quote reflects an intent that may have been amended since.
One caveat when reading a subscription: whether it is being billed and whether the service is provisioned are tracked separately, and they can disagree — a paused or terminated subscription is not a single flag. If a request turns on whether something is "active", establish which sense is meant rather than reading whichever status you see first.
Changing an existing commitment: amend or renew
A change to something the customer already has is not a net new quote. Two dedicated tools exist, and picking between them is the decision this skill can help with:
amend_contractchanges the commitment in place. It opens a DRAFT AMENDMENT quote on the same contract, pre-populated with the contract's current offerings and items.renew_contractcontinues the commitment into a new term. It opens a DRAFT RENEWAL quote which, once processed, creates a new contract pointing back at this one.
Three things follow that are easy to get wrong:
Neither tool changes anything by itself. Both leave a draft for review, and the contract is untouched until that draft is processed. Renewal in particular never happens outright — if a user asks you to just renew something, say that leaving a draft is as far as it goes.
A net new quote cannot be either of these. create_net_new_quote has no contract linkage, so
labelling a quote as a renewal there produces a quote attached to nothing. These tools are the only
route.
Check what is actually live before you change it. The amendment arrives pre-populated from the contract; the subscription is what the customer is being billed for today. When a user describes the current state in a way the draft does not match, the subscription settles it.
Edit the draft, do not rebuild it. What comes back is an ordinary quote — adjust it with
update_quote, create_quote_offering and update_quote_offering, exactly as in the assembly
steps above. The offerings that arrive pre-populated are the existing commitment; recreating them
produces duplicates rather than changes. When describing what an amendment does, read it off the
per-item amendment status rather than diffing by hand.
Each tool documents its own preconditions, and they differ in ways worth reading rather than assuming — the states that block an amendment are not the states that block a renewal.
Related skills
monetizenow-data-retrieval for resolving accounts, offerings, and rates and handling multiple
matches. monetizenow-pricing-strategy for setting or changing any price on the quote.