Customer & Sales package

Quote approval with discount tiers

Sales reps submit a quote; a discount authority table sets who approves, and each approver can approve, reject or counter before the CPQ is updated.

Starts from a formIntermediate~15 min setupv1.0.0

About this package

What it does

Quote approval with discount tiers enforces your discount authority without chasing approvals over chat. The sales rep fills in the start form: quote id, customer, product, annual list price, discount, term, payment terms and a justification.

The workflow works out the net annual price and the deal value over the term, then evaluates the Discount authority decision table. Up to 10% is approved automatically; above that the sales manager approves, above 20% the VP sales as well, and above 30% (or on very large deals) the deal desk and the CFO join. Approvals run in sequence, each with a one-day due date, a reminder and escalation, and each approver can approve (adjusting the approved discount), reject or make a counter-offer.

The final decision is written to the quote in your CPQ system and the rep gets an email: approved with the discount and conditions, rejected with the reason, or the counter-offer to take back to the customer. Adapt the thresholds, the approver chain and the CPQ call to your sales policy.

Starts from a form

Starts from a form: the sales rep submits the quote details (Run dialog in the app, or a button in your CPQ posting to the start API).

Someone fills in a form to start it: the workflow inputs are the start form (Run dialog in the app, or your own portal posting to the API), and people complete User Task forms along the way.

The flow

Step by step

  1. 1

    Quote submitted

    The start form collects the quote id, customer, product, list price, discount, term, payment terms and justification.

  2. 2

    Price the deal

    The net annual price and the deal value over the term are calculated.

  3. 3

    Find the approval path

    The Discount authority decision table returns which approvers are needed: none, sales manager, VP sales, deal desk and CFO.

  4. 4

    Approve in sequence

    Each required approver approves (and can lower the approved discount), rejects or makes a counter-offer.

  5. 5

    Update the CPQ

    The decision and approved discount are recorded on the quote in the CPQ system.

  6. 6

    Tell the rep

    The rep is emailed the approval, the rejection reason or the counter-offer.

Quote approval — A sales rep submits a quote; the discount authority table sets the approval path and each required approver (sales manager, VP sales, deal desk, CFO) approves, rejects or counters in turn. The decision is written to the CPQ system and the rep is emailed. The same canvas you get in the designer after installing.

Forms

The start form and the task forms

The workflow inputs are the start form: the Run dialog renders them, and your own portal can post the same fields. User Tasks show their fields and outcome buttons to the assignee.

Start form

Quote approval

Filled in by whoever starts the process

Quote id * quote_id · textQuote id in the CPQ system
Customer * customer · textCustomer account name
Product * product · select
Platform StandardPlatform ProfessionalPlatform EnterpriseAdd-on: AnalyticsServices: Implementation
Product or plan being quoted
List price (annual) * list_price · number0Annual list price before discount
Currency currency · select
NZDAUDUSDEURGBP
ISO currency code
Discount % * discount_pct · number0Requested discount off list, in percent
Term (months) * term_months · number0Contract term in months
Payment terms payment_terms · select
Annual in advanceQuarterly in advanceMonthly in arrearsNet 30Net 60
Billing and payment terms
Justification * justification · textWhy the discount is needed: competition, volume, strategic logo, timing
Your email * rep_email · emailname@company.comSales rep email: receives the decision
Sales manager (user id) sales_manager_id · textOptional: user id of the sales manager (overrides the install-time default)
VP sales (user id) vp_sales_id · textOptional: user id of the VP sales
Deal desk (user id) deal_desk_id · textOptional: user id of the deal desk analyst
CFO (user id) cfo_id · textOptional: user id of the CFO

User Task

Sales manager approval

Sales manager approval: {{customer}} {{quote_id}} at {{discount_pct}}%

Approved discount % * approved_discount_pct · numberPrefilled: {{approved_discount_pct}}
Conditions (e.g. annual prepayment, case study) conditions · text
Comment for the rep comment · text
ApproveRejectCounter-offer

User Task

VP sales approval

VP sales approval: {{customer}} {{quote_id}} at {{discount_pct}}%

Approved discount % * approved_discount_pct · numberPrefilled: {{approved_discount_pct}}
Conditions (e.g. annual prepayment, case study) conditions · text
Comment for the rep comment · text
ApproveRejectCounter-offer

User Task

Deal desk review

Deal desk approval: {{customer}} {{quote_id}} at {{discount_pct}}%

Approved discount % * approved_discount_pct · numberPrefilled: {{approved_discount_pct}}
Gross margin % at this discount * gross_margin_pct · number0
Non-standard terms non_standard_terms · boolean
Conditions (e.g. annual prepayment, case study) conditions · text
Comment for the rep comment · text
ApproveRejectCounter-offer

User Task

CFO approval

CFO approval: {{customer}} {{quote_id}} at {{discount_pct}}%

Approved discount % * approved_discount_pct · numberPrefilled: {{approved_discount_pct}}
Conditions (e.g. annual prepayment, case study) conditions · text
Comment for the rep comment · text
ApproveRejectCounter-offer

From your code

Start a run over the API

Every workflow can be started over REST, MCP or the CLI, whatever its trigger, with the sample input below. Runs start straight away on the published version; replace <workflow id> with the id the install created.

REST

shell
curl -X POST "$USERTASKS_URL/api/v1/workflows/start" \
  -H "Authorization: Bearer $USERTASKS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"workflow_id":"<workflow id>","variables":{"quote_id":"Q-2026-0457","customer":"Fourth Coffee","product":"Platform Professional","list_price":60000,"currency":"USD","discount_pct":18,"term_months":24,"payment_terms":"Annual in advance","justification":"Competitive evaluation against an incumbent; two-year commitment with annual prepayment.","rep_email":"sam.patel@example.com"}}'

CLI

shell
usertasks workflows inputs <workflow id>          # the start form: keys, types, required
usertasks workflows run <workflow id> --input quote_id=Q-2026-0457 --input customer="Fourth Coffee" --input product="Platform Professional" --input list_price=60000 … --wait

Inbound webhook

shell
usertasks webhooks create <workflow id>          # prints the hook slug and secret once
curl -X POST "$USERTASKS_URL/api/webhooks/inbound?hook=<slug>" \
  -H "Authorization: Bearer <webhook secret>" -H "Content-Type: application/json" \
  -d '{"quote_id":"Q-2026-0457","customer":"Fourth Coffee","product":"Platform Professional","list_price":60000,"currency":"USD","discount_pct":18,"term_months":24,"payment_terms":"Annual in advance","justification":"Competitive evaluation against an incumbent; two-year commitment with annual prepayment.","rep_email":"sam.patel@example.com"}'

What's included

7 assets, ready to adapt

TypeNameDetails
Email templateQuote approvedSent to the sales rep when the quote discount is approved.
Email templateQuote counter-offerSent to the sales rep when an approver proposes a different discount.
Email templateQuote rejectedSent to the sales rep when an approver rejects the discount.
IntegrationCPQ system
API referenceRecord quote approvalPOST /quotes/{{quote_id}}/approval — Write the approval decision back to the quote in the CPQ system: approved (with the approved discount), rejected or counter-offer.
Decision tableDiscount authority6 rules — Who has to approve a quote discount, by discount %, deal size and term. Approvals run in sequence: sales manager, VP sales, deal desk, CFO. First matching rule wins.
WorkflowQuote approval33 steps — A sales rep submits a quote; the discount authority table sets the approval path and each required approver (sales manager, VP sales, deal desk, CFO) approves, rejects or counters in turn. The decision is written to the CPQ system and the rep is emailed.

Requirements

What you connect it to

Credentials never travel in a package. The install wizard asks for what your environment must provide, or installs it incomplete until you finish setup.

Needs

  • REST API — A REST API integration: set its base URL and credentials on install.
  • Assignees — People in your workspace to receive the User Tasks (picked on install).
  • Email — Email delivery configured for the instance (EMAIL_PROVIDER), used for notifications.

After installing

  1. CPQ system: set the base URL and API token of your CPQ or CRM quoting API. Record quote approval posts to /quotes/{quote_id}/approval; adjust the path and body in Integrations.
  2. Assignees: pick the default sales manager, VP sales, deal desk analyst and CFO (runs can pass sales_manager_id, vp_sales_id, deal_desk_id and cfo_id, for example from the rep's team).
  3. Edit the Discount authority rules to your delegation of authority (discount bands, deal size, short terms).
  4. Email: configure EMAIL_PROVIDER so reps receive the decision emails (the steps continue on error).

Asked for on install

  • Integration “CPQ system”Required

    • Tokenconfig.auth_config.token
    • Base urlconfig.base_urldefault https://cpq.example.com/api· optional
  • Workflow “Quote approval” assigneesRequired

    • User for step “Sales manager approval”nodes.8.config.assignee_id
    • User for step “VP sales approval”nodes.12.config.assignee_id
    • User for step “Deal desk review”nodes.16.config.assignee_id
    • User for step “CFO approval”nodes.20.config.assignee_id

Install

Install it in your workspace

Works on UserTasks cloud and on any self-hosted instance. Installing creates the assets above; nothing runs until you complete setup and start it.

In the app

  1. Download quote-approval-discount-tiers-1.0.0.utpkg.
  2. Open Automations → Packages and drag the file onto the page (or choose Import package). Browse gallery there lists every gallery package without downloading by hand.
  3. Pick the file. The wizard verifies the checksum, every file hash and the signature, and shows the readme.
  4. Review the changes (what is created) and the data rows.
  5. Fill in the requirements, or tick Keep incomplete and finish later with Complete setup.
  6. Done: the workflow is published and active once setup is complete.

With the CLI

shell
curl -fLO https://usertasks.com/gallery/quote-approval-discount-tiers-1.0.0.utpkg
usertasks packages inspect quote-approval-discount-tiers-1.0.0.utpkg       # offline: checksum, hashes, signature
usertasks packages install quote-approval-discount-tiers-1.0.0.utpkg --dry-run
usertasks packages install quote-approval-discount-tiers-1.0.0.utpkg       # prompts for each requirement
usertasks packages install quote-approval-discount-tiers-1.0.0.utpkg --keep-incomplete --yes   # in CI; finish with:
usertasks packages complete quote-approval-discount-tiers -f values.yaml

Verify the download

File SHA-256
8b640d57605d53025ecf69f5be266ffe8edab5e2e3b2814cd25823f6946ff431
Package checksum (what is signed)
sha256:e706c946a9c298fcb105edbfb59401aefe547738c7eda8ac396521cdd926a80f
Signer
Unsigned preview build — compare the SHA-256 above

shasum -a 256 quote-approval-discount-tiers-1.0.0.utpkg should print the file SHA-256. How gallery packages are signed.

Versions

Version 1.0.0

  1. v1.0.02026-10-26First release.

Installing a newer version upgrades in place: local credentials and requirement values are kept, and changes you made are flagged first. How packages work

More packages

Related

Browse the whole gallery