QuoteNag Integrations

Connect your quote workflow. Let QuoteNag handle the follow-up.

Connect the tools that already know when a quote was sent and let QuoteNag handle the follow-up. Use the API to create, find, and stop campaigns. Use signed webhooks to send decisions and follow-up activity back to your workflow.

Quick Start

Get a working automation in four steps

Start with one campaign and one event. Add more workflow logic after you confirm the connection works.

  1. 1
    Create an API key

    Open Integrations > API Keys. Give the key a clear label and copy it when it appears. The full key is shown once.

  2. 2
    Test the connection

    Send an authenticated request to GET /api/v1/account. A valid connection returns safe account details and API version v1.

  3. 3
    Create a campaign

    Send the client and quote details to POST /api/v1/campaigns. Include external_reference so workflow retries do not create duplicates.

  4. 4
    Receive QuoteNag events

    Add your automation tool's HTTPS URL under Integrations > Webhooks. Filter incoming events by the exact event names documented below.

Authentication

Send your API key as a bearer token

Every API request must include the key in the Authorization header. QuoteNag does not accept API keys in URLs, query strings, or JSON bodies.

Authorization: Bearer qn_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Find your key in QuoteNag

Sign in, open Integrations, then choose API Keys. If you lose the complete key, revoke it and create a new one.

Test Your Connection

Use this endpoint before creating campaigns. It confirms the key, account, subscription access, and API version without returning campaign or billing data.

GET https://quotenag.gottools.co/api/v1/accountAuthorization: Bearer qn_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Accept: application/json

HTTP 200 response

{
  "data": {
    "id": 123,
    "name": "Lyte Painting",
    "api_version": "v1"
  }
}
API Reference

Create, find, and stop quote campaigns

All API requests are restricted to the QuoteNag account that owns the bearer key. An API request cannot choose another account.

POST

/api/v1/campaigns

Creates a quote campaign and schedules its follow-ups. Each QuoteNag account can create up to 500 campaigns per calendar month.

FieldRequiredWhat it does
client_nameYesClient name, up to 120 characters.
client_emailYesValid client email, up to 190 characters.
quote_titleYesShort quote title, up to 190 characters.
quote_summaryYesUseful context about the work or estimate.
quote_amountNoAmount as a string or number using QuoteNag's existing display convention.
quote_expires_atNoA non-past YYYY-MM-DD date in the account timezone.
external_referenceNoYour source record ID. Recommended for retry protection. Maximum 160 characters.
followupsNoOne to three custom follow-ups. Omit it to use the safe schedule below.

Minimum request

{
  "client_name": "Jamie Rivera",
  "client_email": "jamie@example.com",
  "quote_title": "Roof repair quote",
  "quote_summary": "Repair damaged shingles and flashing.",
  "external_reference": "estimate-1042"
}

What happens when you omit the schedule

QuoteNag creates one runnable follow-up scheduled three days after campaign creation. It uses the account's first saved follow-up subject and body, or QuoteNag's built-in first-message text if that template is empty. QuoteNag does not currently have an account-level default cadence.

Custom follow-up request example
{
  "client_name": "Morgan Lee",
  "client_email": "morgan@example.com",
  "quote_title": "Kitchen remodel quote",
  "quote_summary": "Cabinets, counters, and installation.",
  "quote_amount": "$12,500.00",
  "quote_expires_at": "2030-08-15",
  "external_reference": "estimate-1042",
  "followups": [
    {
      "timing_type": "days",
      "days": 2,
      "subject": "Quick check-in on {{quote_title}}",
      "body": "Hi {{client_name}}, just checking in on the quote."
    }
  ]
}

Duplicate protection

external_reference is unique inside one QuoteNag account and comparison is case-sensitive. An identical retry returns the existing campaign with HTTP 200 and deduplicated: true. Reusing the same reference with different campaign data returns HTTP 409 and leaves the original campaign unchanged. Requests without an external reference always create a new campaign.

New campaign response

{
  "data": {
    "id": 123,
    "campaign_url": "https://quotenag.gottools.co/app/campaign/123",
    "external_reference": "estimate-1042",
    "client_name": "Jamie Rivera",
    "client_email": "jamie@example.com",
    "quote_title": "Roof repair quote",
    "quote_summary": "Repair damaged shingles and flashing.",
    "quote_amount": null,
    "quote_expires_at": null,
    "status": "Pending",
    "created_at": "2026-07-10 12:00:00",
    "updated_at": "2026-07-10 12:00:00",
    "deduplicated": false
  }
}
GET

Find Quote Campaign

Use one of these focused lookups. QuoteNag does not perform partial title searches or general CRM searches.

GET /api/v1/campaigns/123Returns one owned campaign by ID, or HTTP 404.
GET /api/v1/campaigns?external_reference=estimate-1042Exact, account-scoped reference. Returns a list with zero or one match.
GET /api/v1/campaigns?client_email=morgan%40example.comEmail is not unique. Returns up to 50 matches, newest first.
GET /api/v1/campaignsReturns the account's latest 50 campaigns.

Collection lookups return {"data":[]} when nothing matches. Do not send both supported collection filters in one request.

POST

/api/v1/campaigns/{id}/stop

Stops a Pending campaign without deleting it. QuoteNag cancels remaining scheduled follow-ups and preserves sent or failed history. No request body is required.

  • Pending: changes to Stopped and cancels remaining scheduled follow-ups.
  • Stopped: returns a safe HTTP 200 result without changing the status.
  • Accepted or Declined: remains resolved and is never overwritten with Stopped.
  • Another account or unknown ID: returns the same non-leaking HTTP 404 response.
POST https://quotenag.gottools.co/api/v1/campaigns/123/stop
Authorization: Bearer qn_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Webhooks

Send quote activity to your other tools

QuoteNag sends a signed JSON request to every active webhook endpoint after supported campaign activity. Add endpoints under Integrations > Webhooks.

campaign.created

Sent after a manual or API campaign and its follow-ups commit successfully.

campaign.accepted

Sent once for the first valid accepted decision. Filter on data.decision = accepted.

campaign.declined

Sent once for the first valid declined decision. Filter on data.decision = declined.

followup.sent

Sent after the mailer succeeds and QuoteNag records the follow-up as sent.

Existing events followup.failed and integration.test also remain available. They are not part of the four Pabbly trigger mappings above.

Stable event envelope

{
  "id": "evt_11111111111111111111111111111111",
  "event": "campaign.created",
  "sent_at": "2026-07-10T19:00:00+00:00",
  "occurred_at": "2026-07-10T19:00:00+00:00",
  "api_version": "v1",
  "data": {}
}

The event ID stays the same across retry attempts for one logical event. Receivers should ignore unknown additive fields so future compatible additions do not break the workflow.

Webhook signing

QuoteNag signs the exact raw request body with the endpoint's signing secret. The signature is a lowercase hexadecimal HMAC-SHA256 digest with the sha256= prefix.

X-QuoteNag-Event: campaign.created
X-QuoteNag-Event-ID: evt_11111111111111111111111111111111
X-QuoteNag-API-Version: v1
X-QuoteNag-Signature: sha256=<hex HMAC digest>

Verify the signature against the raw body before parsing or acting on the payload.

Delivery and retries

  • Any HTTP 2xx response counts as successful delivery.
  • Transport errors, HTTP 408, 425, 429, and 5xx responses receive up to three synchronous attempts.
  • Other HTTP 4xx responses are not retried.
  • Each attempt has a 10-second timeout and redirects are not followed.
  • Delivery requires PHP cURL and is pinned to a validated public destination IP to reduce server-side request forgery risk.
  • QuoteNag does not currently provide a delayed replay queue or dead-letter screen.

Webhook Event Payloads

These sanitized examples are loaded from the same checked fixtures used to verify QuoteNag's production serializers.

New Quote Campaign: campaign.created
{"error":"Example unavailable"}
Quote Accepted: campaign.accepted
{"error":"Example unavailable"}
Quote Declined: campaign.declined
{"error":"Example unavailable"}
Follow-Up Sent: followup.sent
{"error":"Example unavailable"}
Manual Pabbly Setup

Connect Pabbly before the native QuoteNag app is public

This setup uses Pabbly's webhook and HTTP/API request steps. It does not use or imply a live native QuoteNag app.

No per-event selector in QuoteNag

Every active QuoteNag endpoint receives every supported event. Use a Pabbly filter on the exact event value, plus data.decision for accepted or declined workflows.

Receive QuoteNag events in Pabbly

  1. Create a workflow in Pabbly Connect.
  2. Choose the appropriate Webhook by Pabbly trigger and copy its generated HTTPS webhook URL.
  3. In QuoteNag, open Integrations > Webhooks, create an endpoint, and paste the Pabbly URL.
  4. Use Send test to confirm connectivity. This sends integration.test.
  5. To capture the fields for a real trigger, perform the matching action in a test campaign: create a campaign, accept or decline it, or let a scheduled follow-up send.
  6. In Pabbly, capture the request and filter it using the mapping below.
Workflow outcomeFilter
New Quote Campaignevent = campaign.created
Quote Acceptedevent = campaign.accepted and data.decision = accepted
Quote Declinedevent = campaign.declined and data.decision = declined
Follow-Up Sentevent = followup.sent

Create QuoteNag campaigns from Pabbly

  1. Create a QuoteNag API key and store it in Pabbly's protected authentication or header field.
  2. Add an HTTP/API request action in Pabbly.
  3. Set the method to POST and the URL to https://quotenag.gottools.co/api/v1/campaigns.
  4. Add Authorization: Bearer YOUR_QUOTENAG_API_KEY and Content-Type: application/json.
  5. Map the four required fields and a stable external_reference from the source quote or estimate.
  6. Test the request, then confirm the campaign appears in QuoteNag.
{
  "client_name": "Jamie Rivera",
  "client_email": "jamie@example.com",
  "quote_title": "Roof repair quote",
  "quote_summary": "Repair damaged shingles and flashing.",
  "external_reference": "estimate-1042"
}
Error Responses

Use the status and code to choose the next step

HTTPCodeWhat to do
401missing_api_keyAdd the bearer Authorization header.
401invalid_api_keyCheck the key and bearer format. Do not put the key in the URL.
401revoked_api_keyCreate a replacement key and update the workflow.
401inactive_accountRestore account access before retrying.
402subscription_requiredActivate or restore the QuoteNag subscription.
404resource_not_foundCheck the campaign ID. QuoteNag returns the same result for unknown and unowned records.
409external_reference_conflictDo not overwrite the existing campaign. Use the source record's correct stable reference.
429campaign_monthly_limit_reachedThe account has created 500 campaigns this calendar month. Wait until next month before creating another new campaign.
422validation_errorFix the named field and stable reason before retrying.
422invalid_requestCheck JSON syntax and request-level values.
{
  "error": "Client email is invalid.",
  "code": "validation_error",
  "field": "client_email",
  "reason": "invalid_email"
}
Security

Keep the connection useful without exposing the keys

  • Keep API keys private

    Store them in protected credential fields. Never add them to URLs, screenshots, source control, normal logs, or support messages.

  • Revoke compromised keys

    Revoke the affected key under Integrations > API Keys. Revocation takes effect on the next request.

  • Verify webhook signatures

    Generate HMAC-SHA256 from the exact raw request body and compare it with X-QuoteNag-Signature.

  • Use HTTPS

    Use HTTPS for API calls and all new webhook endpoints. QuoteNag keeps HTTP webhook support only for backward compatibility with existing consumers.

  • Expect account isolation

    API keys, campaign lookups, duplicate checks, and webhook endpoints stay inside the owning QuoteNag account.