All Posts Jobber Integration

Jobber Quote Forms on WordPress: Line Items, Pricing, and Custom Configurations

Master Jobber quote forms on WordPress. Line items, REST API integration, profession-specific configurations, and dynamic pricing for service businesses.

You’ve probably spent hours manually building quotes in spreadsheets. Line items scattered across email threads. Clients asking for revisions. No real pricing control. No integration with your actual Jobber account.

Here’s the thing: you don’t have to.

A properly configured Jobber quote form on WordPress does all that work automatically. It captures client information, builds line-item pricing directly into your Jobber system, and creates a professional quote that syncs instantly. No copy-paste. No mistakes. No manual data entry.

The difference between a basic request form and a quote form is massive. And when you master the REST API integration, you can build quote builders that scale with your business.

Let’s walk through exactly how to do this.

Request Forms vs. Quote Forms: Know the Difference

This distinction matters more than you think.

Request forms are simple. They’re for capturing basic information: name, contact details, which service they’re interested in, maybe some notes. Jobber creates a service request. Perfect for consultations or quick bookings. But there’s no pricing, no line items, no formal quote.

Quote forms are different. They’re designed for projects with multiple components and actual pricing. When someone submits a quote form, Jobber creates a quote object with line items, total cost, and everything a client needs to approve the project before work starts.

Here’s when to use each:

  • Request form: Home inspection booking. “Tell us your address and preferred time.” Creates a service request.
  • Quote form: Roof replacement. Shingle removal, new shingles, felt paper, drip edge, permit filing. Different prices for each. Client needs to see the breakdown and approve before you start.

The technical difference is the form type parameter and what Jobber creates in the backend. Request forms create service requests. Quote forms create quotes with line items.

For service businesses, the quote form is almost always the better choice if you’re dealing with anything beyond a flat-rate service.

Basic Quote Form Shortcode

Starting simple: here’s the Jobber booking form shortcode configured for quotes.

[jobber_booking_form type="quote" title="Get a Quote" show_address="yes" show_service="yes" show_company="yes"]

Drop that into any WordPress page. The Jobber plugin handles the rest. The form captures:

  • First and last name
  • Email and phone
  • Address (if show_address="yes")
  • Service selection (if show_service="yes")
  • Company name (if show_company="yes")
  • Message or notes

When submitted, Jobber creates a quote in your account. The client gets a confirmation email. You get notified.

But here’s the catch: this basic shortcode doesn’t handle line items. There’s no pricing breakdown. It’s a data capture form, not a quote builder.

For anything more complex—multiple services, different pricing tiers, add-ons, customizations—you need the REST API.

Line Items and the Jobber REST API

This is where the real power lives.

The Jobber REST API has a quote endpoint that accepts line items directly. Each line item gets a name, unit price, and quantity. Jobber calculates the total automatically. The quote syncs to your Jobber account instantly.

Here’s the full payload structure:

{
  "first_name": "Jane",
  "last_name": "Doe",
  "email": "[email protected]",
  "phone": "555-123-4567",
  "title": "Spring cleanup quote",
  "message": "Two acres, mostly flat terrain",
  "line_items": [
    { "name": "Lawn Mowing", "unit_price": 75.0, "quantity": 1 },
    { "name": "Edging", "unit_price": 25.0, "quantity": 1 },
    { "name": "Debris Removal", "unit_price": 50.0, "quantity": 1 }
  ]
}

Each line item is independent. You set the name, the price per unit, and how many units. Jobber handles the multiplication and calculates the total.

The title field becomes the quote name in Jobber. The message is just notes. Everything else maps to your client record.

Building a Custom Quote Form with the REST API

Now let’s actually build something useful.

You’ve got a landscape company. Different services. Different pricing. Clients should be able to select what they want, see the price update in real time, and submit everything at once.

Here’s the JavaScript that powers it:

async function submitQuote(formData) {
  const payload = {
    first_name: formData.firstName,
    last_name: formData.lastName,
    email: formData.email,
    title: `${formData.service} Quote`,
    line_items: formData.selectedServices.map((s) => ({
      name: s.name,
      unit_price: s.price,
      quantity: s.quantity || 1,
    })),
  };

  const res = await fetch(jobberIntegration.restUrl + "jobber/v1/quote", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "X-WP-Nonce": jobberIntegration.nonce,
    },
    body: JSON.stringify(payload),
  });

  return res.json();
}

Breaking this down:

  1. formData comes from your HTML form. It contains the client’s name, email, and the services they selected.
  2. line_items is an array. Each selected service becomes a line item. If they select lawn mowing with quantity 2, it’s {name: "Lawn Mowing", unit_price: 75, quantity: 2}.
  3. fetch sends the payload to the Jobber REST API endpoint at jobber/v1/quote.
  4. The X-WP-Nonce header is a WordPress security token. Jobber’s plugin provides this automatically.
  5. Jobber returns the created quote object. You can then redirect the client or show a success message.

The form itself would be HTML checkboxes or a select menu. When the client checks “Lawn Mowing,” you add it to selectedServices. When they submit, the JavaScript runs this function and creates the quote instantly.

No manual entry. No spreadsheet. No syncing.

Real-World Examples: Profession-Specific Configurations

Different trades have different needs. Let’s look at how actual service businesses set this up.

Roofing

A roof replacement quote has multiple components:

{
  "title": "New Roof - Asphalt Shingles",
  "line_items": [
    { "name": "Shingle Removal (Labor)", "unit_price": 2.5, "quantity": 2500 },
    {
      "name": "Asphalt Shingles (Premium)",
      "unit_price": 0.75,
      "quantity": 2500
    },
    { "name": "Felt Underlayment", "unit_price": 0.15, "quantity": 2500 },
    { "name": "Drip Edge (Linear Feet)", "unit_price": 1.25, "quantity": 240 },
    { "name": "Roofing Permit", "unit_price": 350.0, "quantity": 1 }
  ]
}

Notice the quantities. You’re not just saying “Shingle Removal: $6,250.” You’re showing the client the unit price ($2.50 per square foot) and the quantity (2,500 sq ft). It’s transparent. It’s professional.

HVAC

A heating system replacement:

{
  "title": "Complete HVAC System Replacement",
  "line_items": [
    {
      "name": "Furnace (High-Efficiency)",
      "unit_price": 2800.0,
      "quantity": 1
    },
    { "name": "AC Condenser Unit", "unit_price": 1500.0, "quantity": 1 },
    {
      "name": "Installation Labor (8 Hours)",
      "unit_price": 150.0,
      "quantity": 8
    },
    {
      "name": "Smart Thermostat (Installed)",
      "unit_price": 450.0,
      "quantity": 1
    },
    { "name": "Ductwork Modifications", "unit_price": 600.0, "quantity": 1 }
  ]
}

HVAC quotes are equipment-heavy. You’re mixing product pricing (the furnace costs $2,800) with service pricing (installation is $150/hour). The line-item structure handles both perfectly.

Cleaning Services

A commercial cleaning proposal:

{
  "title": "Office Cleaning - Initial Assessment",
  "line_items": [
    {
      "name": "Conference Rooms (Deep Clean)",
      "unit_price": 75.0,
      "quantity": 3
    },
    { "name": "Bathrooms (Deep Clean)", "unit_price": 50.0, "quantity": 2 },
    { "name": "Kitchen Deep Clean", "unit_price": 100.0, "quantity": 1 },
    { "name": "Carpet Shampooing", "unit_price": 0.75, "quantity": 1200 }
  ]
}

For cleaning, you’re often pricing by the room or by square footage. Breaking it into line items shows the client exactly what you’re charging for. It builds confidence.

Pressure Washing

A pressure washing company quoting a full house wash:

{
  "title": "Full Property Pressure Wash",
  "line_items": [
    { "name": "House Exterior Wash", "unit_price": 0.15, "quantity": 2800 },
    { "name": "Driveway Pressure Wash", "unit_price": 0.18, "quantity": 1200 },
    { "name": "Deck Cleaning", "unit_price": 0.25, "quantity": 400 },
    { "name": "Fence Pressure Wash", "unit_price": 0.12, "quantity": 800 }
  ]
}

Pressure washing is usually priced by square footage. You’re charging $0.15 per square foot for the house, $0.18 for the driveway, etc. The line items show the breakdown clearly.

Pre-Populated Quote Forms for Service Pages

Here’s a pro move: different services get different quote forms.

Your roofing page has a quote form pre-populated with roofing line items. Your HVAC page has HVAC line items. When a client clicks “Get a Quote” on the roof page, they see roof-specific services already listed.

You’d do this with shortcode parameters or by rendering different forms based on the page:

// In your theme or plugin
if ( is_page( 'roofing-services' ) ) {
    echo do_shortcode( '[jobber_quote_form service_type="roofing"]' );
} elseif ( is_page( 'hvac-services' ) ) {
    echo do_shortcode( '[jobber_quote_form service_type="hvac"]' );
}

Then your custom shortcode handler loads the appropriate line items from Jobber (via the API) and displays them pre-checked or pre-selected.

The client sees what they’re getting quoted on immediately. No confusion. No “Let me figure out what service you offer.”

Dynamic Pricing Based on User Selections

This is where quote forms become interactive experiences.

Imagine a lawn care quote form. The client selects:

  • Lawn size (dropdown: “Small”, “Medium”, “Large”)
  • Add-ons (checkboxes: “Edging”, “Mulch”, “Aeration”)
  • Frequency (radio: “One-time”, “Monthly”, “Seasonal”)

The price updates in real time as they make selections. They hit submit and the quote is created with exactly what they chose.

Here’s the JavaScript pattern:

const servicePricing = {
  lawn_small: 49.99,
  lawn_medium: 74.99,
  lawn_large: 99.99,
  edging: 25.0,
  mulch: 50.0,
  aeration: 40.0,
};

function updateQuotePreview() {
  const size = document.querySelector('select[name="lawn_size"]').value;
  const addOns = Array.from(
    document.querySelectorAll('input[name="add_ons"]:checked'),
  ).map((checkbox) => checkbox.value);

  let total = servicePricing[size] || 0;
  addOns.forEach((addon) => {
    total += servicePricing[addon] || 0;
  });

  document.querySelector(".quote-total").textContent = `$${total.toFixed(2)}`;

  // Store for submission
  window.selectedServices = [{ name: size, price: servicePricing[size] }];
  addOns.forEach((addon) => {
    window.selectedServices.push({ name: addon, price: servicePricing[addon] });
  });
}

// Update preview on every change
document.querySelectorAll('select, input[type="checkbox"]').forEach((el) => {
  el.addEventListener("change", updateQuotePreview);
});

The client sees the price change instantly. When they submit, the JavaScript sends all their selections as line items to Jobber. It feels modern. It feels like their options matter.

Multi-Step Quote Wizards

For really complex projects, a single-page form isn’t enough.

Think about a home renovation. Step 1: What rooms? Step 2: What upgrades in each? Step 3: Timeline? Step 4: Budget range? By the end, you’ve got dozens of line items.

A multi-step wizard (sometimes called a “form wizard”) walks the client through this step-by-step. At the end, you submit everything at once via the REST API.

The structure looks like:

const wizard = {
  steps: [
    {
      title: "Select Rooms",
      fields: ["kitchen", "bathroom", "bedroom", "living_room"],
      next: "upgrades",
    },
    {
      title: "Choose Upgrades",
      fields: ["new_cabinets", "granite_counters", "new_flooring"],
      next: "timeline",
    },
    {
      title: "Timeline & Budget",
      fields: ["start_date", "budget_range"],
      next: "review",
    },
    {
      title: "Review Quote",
      fields: [],
      submit: true,
    },
  ],
};

Each step collects data. When the client clicks “Next,” you validate and move forward. At the end, you calculate line items based on all their selections and submit via the Jobber API.

A roofing company might use this for “choose your shingles” → “choose warranty” → “choose timeline” → “review total.”

Quote Follow-Up Automation with Webhooks

Once a quote is created, you can automate what happens next.

Jobber fires webhooks when quotes are updated. If you’re listening for those events, you can trigger actions on your site.

add_action('jobber_webhook_quote/update', function($payload) {
    $quoteData = $payload['data'];

    // When a quote is approved, celebrate and schedule
    if ($quoteData['status'] === 'approved') {
        // Send internal notification to your team
        wp_mail(
            '[email protected]',
            'New Approved Quote: ' . $quoteData['title'],
            'Quote ID: ' . $quoteData['id'] . ' | Client: ' . $quoteData['client']['name']
        );

        // Could also trigger a Zapier/Make workflow
        // Or automatically schedule a follow-up call
    }

    // When a quote is rejected, log it and reach out
    if ($quoteData['status'] === 'rejected') {
        error_log('Quote rejected: ' . $quoteData['id']);
        // Maybe trigger a discount offer?
    }
});

Real-world example: A client approves a quote. Your webhook listener fires. You:

  1. Email your field team with the job details.
  2. Trigger a calendar integration to block the estimated time.
  3. Send the client an automated email: “Thanks for approving! Here’s what happens next…”
  4. Log it to your CRM for follow-up tracking.

All automatic. All triggered by that single webhook.

Handling Returning Customers and Duplicate Quotes

Here’s a practical problem: a client comes back a year later asking for a new quote.

You could create a brand-new quote from scratch. Or you could duplicate the old quote and adjust the line items.

Jobber’s API supports this:

async function createQuoteFromPrevious(previousQuoteId, updatedLineItems) {
  const res = await fetch(`jobber/v1/quote/${previousQuoteId}/duplicate`, {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "X-WP-Nonce": jobberIntegration.nonce,
    },
    body: JSON.stringify({
      line_items: updatedLineItems,
      title: `${new Date().getFullYear()} Maintenance - Annual Refresh`,
    }),
  });

  return res.json();
}

This is powerful for:

  • Annual service quotes (cleaning, maintenance, inspections)
  • Repeat projects (landscaping every spring)
  • Client retention (familiar pricing, easy to approve again)

You retrieve the old quote from Jobber, duplicate it, adjust the line items for inflation or new services, and submit. The client sees “This is similar to your 2025 quote, just updated for this year.”

Pro Tips for Quote Form Success

A few things we’ve learned from working with Jobber forms at scale:

1. Always show the total. Even if it’s just a preview, clients want to see the number. It builds trust. Update it in real time as they select options.

2. Be specific with line item names. Not “Labor: $1,200.” Say “Installation Labor (8 Hours at $150/hr).” The specificity kills objections.

3. Test the API nonce. The WordPress security token needs to be fresh. If your quotes aren’t submitting, nine times out of ten it’s an expired or invalid nonce.

4. Store submissions before posting. If the API call fails, you don’t want to lose the client’s data. Save it locally first, then submit. Show them a success page only after confirmation from Jobber.

5. Mobile is mandatory. Test your quote forms on mobile. If they’re hard to use on a phone, you’ll lose mobile clients.

6. Provide instant confirmation. When they submit, acknowledge it immediately. “Your quote is being created…” then “Success! Check your email for details.”

Connecting Everything Back to Your Jobber Account

The beauty of using the REST API is that everything syncs instantly.

When a quote is created via your WordPress form, it appears in your Jobber account within seconds. You see the client record. You see the quote with all line items. You can approve it, mark it up, send it for client signature, convert it to a job—everything happens in Jobber.

Your WordPress site is the front door. Jobber is the engine. The API is the bridge.

If you’re building an agency that manages multiple service businesses, this scales beautifully. Each client gets their own quote form, their own branding, their own service offerings. All of it syncs to the same Jobber account in the backend.

Where to Go from Here

You’ve got the pieces now. Basic shortcodes for simple quotes. REST API payloads for complex line items. JavaScript patterns for dynamic forms. Webhook automation for follow-ups.

Start with the basic shortcode. Get comfortable with how Jobber receives and processes quotes. Then layer in the REST API. Build a custom form. Test it. Iterate.

Once you’ve nailed quote forms, the whole sales process gets smoother. Clients see pricing instantly. You have clean data in Jobber. Your team can focus on executing work, not chasing down quote details.

That’s the power of proper integration.

For a deeper dive into the full Jobber WordPress ecosystem—request forms, custom field mapping, webhook strategies, multi-site setups—check out our Complete Jobber WordPress Integration Guide.

For specific patterns on building custom booking forms without iframes, see Custom Jobber Booking Forms.

And if you’re building this for agency clients, our Agency Playbook for Jobber + WordPress walks through the whole operation.

The quote form is just the beginning. Let’s build something that actually works.


Ready to connect Jobber to your WordPress site? Native forms, real-time API, no Zapier needed. Get Jobber Integration Pro – $99/year

Free Discovery Call

Start With a Conversation, Not a Commitment

Every engagement begins with a free 30-minute discovery call. We'll map what's slowing your business down and tell you exactly what we'd fix first – no pitch deck, no obligation.