Skip Navigation
Show nav
Heroku Dev Center Dev Center
  • Get Started
  • Documentation
  • Changelog
  • Search
Heroku Dev Center Dev Center
  • Get Started
    • Node.js
    • Ruby on Rails
    • Ruby
    • Python
    • Java
    • PHP
    • Go
    • Scala
    • Clojure
    • .NET
  • Documentation
  • Changelog
  • More
    Additional Resources
    • Home
    • Elements
    • Products
    • Pricing
    • Careers
    • Help
    • Status
    • Events
    • Podcasts
    • Compliance Center
    Heroku Blog

    Heroku Blog

    Find out what's new with Heroku on our blog.

    Visit Blog
  • Log in or Sign up
View categories

Categories

  • Heroku Architecture
    • Compute (Dynos)
      • Dyno Management
      • Dyno Concepts
      • Dyno Behavior
      • Dyno Reference
      • Dyno Troubleshooting
    • Stacks (operating system images)
    • Networking & DNS
    • Platform Policies
    • Platform Principles
    • Buildpacks
  • Developer Tools
    • AI Tools
    • Command Line
    • Heroku VS Code Extension
  • Deployment
    • Deploying with Git
    • Deploying with Docker
    • Deployment Integrations
  • Continuous Delivery & Integration (Heroku Flow)
    • Continuous Integration
  • Language Support
    • Node.js
      • Troubleshooting Node.js Apps
      • Working with Node.js
      • Node.js Behavior in Heroku
    • Ruby
      • Rails Support
        • Working with Rails
      • Working with Bundler
      • Working with Ruby
      • Ruby Behavior in Heroku
      • Troubleshooting Ruby Apps
    • Python
      • Working with Python
      • Background Jobs in Python
      • Python Behavior in Heroku
      • Working with Django
    • Java
      • Java Behavior in Heroku
      • Working with Java
      • Working with Maven
      • Working with Spring Boot
      • Troubleshooting Java Apps
    • PHP
      • PHP Behavior in Heroku
      • Working with PHP
    • Go
      • Go Dependency Management
    • Scala
    • Clojure
    • .NET
      • Working with .NET
  • Databases & Data Management
    • Heroku Postgres
      • Postgres Basics
      • Postgres Getting Started
      • Postgres Performance
      • Postgres Data Transfer & Preservation
      • Postgres Availability
      • Postgres Special Topics
      • Migrating to Heroku Postgres
    • Heroku Key-Value Store
    • Apache Kafka on Heroku
    • Other Data Stores
  • AI
    • Heroku Inference
      • Inference Essentials
      • Inference API
      • AI Models
      • Heroku Inference Quick Start Guides
    • Tool Use
    • Vector Database
    • AI Integrations
  • Monitoring & Metrics
    • Logging
  • App Performance
  • Add-ons
    • All Add-ons
  • Collaboration
  • Security
    • App Security
    • Identities & Authentication
      • Single Sign-on (SSO)
    • Private Spaces
      • Infrastructure Networking
    • Compliance
  • Heroku Enterprise
    • Enterprise Accounts
    • Enterprise Teams
  • Patterns & Best Practices
  • Extending Heroku
    • Platform API
    • App Webhooks
    • Heroku Labs
    • Building Add-ons
      • Add-on Development Tasks
      • Add-on APIs
      • Add-on Guidelines & Requirements
    • Building CLI Plugins
    • Developing Buildpacks
    • Dev Center
  • Accounts & Billing
  • Troubleshooting & Support
  • Integrating with Salesforce
    • Heroku AppLink
      • Working with Heroku AppLink
      • Heroku AppLink Reference
      • Getting Started with Heroku AppLink
    • Heroku Connect (Salesforce sync)
      • Heroku Connect Administration
      • Heroku Connect Reference
      • Heroku Connect Troubleshooting
    • Other Salesforce Integrations
  • Add-ons
  • All Add-ons
  • DNCSolution

DNCSolution

Table of Contents [expand]

  • Key Advantages
  • Prerequisites
  • Provisioning the Add-on
  • Local Setup
  • Dashboard
  • Access via CLI
  • How It Works
  • Integration Example: Authentication and Basic API Call in C#
  • Request Body Parameters
  • Response Body Parameters
  • Monitoring
  • Migrating Between Plans
  • Removing the Add-on
  • Next Steps
  • Troubleshooting, Support, and Feedback
  • Learn More

Last updated November 18, 2025

The DNCSolution add-on is currently in beta.

DNCSolution

This add-on is operated by PossibleNow Inc

Regulatory compliance for Heroku/Salesforce with Do Not Contact & TCPA adherence

The DNCSolution Heroku add-on centralizes and enforces regulatory compliance across all Salesforce and Heroku experiences. It enables developers to perform Do Not Contact (DNC) compliance checks directly from their Heroku applications.

The add-on securely connects to our Compliance Check API, enabling you to verify phone numbers and determine their callable status based on federal and state DNC lists, call curfew (time-of-day calling restrictions), and wireless number checks.

Established Business Relationship (EBR) verification and Reassigned Number Database (RND) checks aren’t included in the Dev plan.

Key Advantages

Adding the DNCSolution Heroku add-on offers critical compliance benefits. This connector supports Heroku users who need a compliance solution outside of Salesforce, as well as Salesforce customers who need an integrated solution.

For Heroku users, the add-on provides a consistent and compliant framework across all deployed environments by seamlessly integrating with Heroku apps.

For developers that also use Salesforce, it provides additional benefits such as:

  • Salesforce Core (Desktop & Mobile): Perform real-time compliance checks in Salesforce Flows, in-app actions, and mobile experiences.
  • Salesforce Data 360 (Data Cloud): Extend contact compliance into data pipelines and the Customer 360 view.
  • Agentforce: Enable agentic experiences with the same trusted compliance APIs your organization already relies on.

What ties these benefits together is Heroku AppLink, which provides a single, trusted integration layer that applies consistently across Salesforce Core, Marketing Cloud, Data Cloud, and Agentforce. It ensures that DNC and TCPA compliance is enforced everywhere, all through a single AppLink service.

For customers using the Dev plan, you can use this add-on independently. It doesn’t require Heroku AppLink.

Prerequisites

The DNCSolution add-on is fully standalone and only requires a Heroku account.

Provisioning the Add-on

Reference the DNCSolution Elements Page for a list of available plans and regions. To get the integration to work with Salesforce, you must also use Heroku Applink and contact addonsupport@possiblenow.com for a custom add-on plan. You don’t need a custom plan if you’re not integrating this add-on for use with Salesforce products.

Users can provision the add-on with the following command:

$ heroku addons:create dnc:test --app YOUR_HEROKU_APP_NAME
Creating dnc:test on YOUR_HEROKU_APP_NAME...
Your add-on has been provisioned successfully

After provisioning the DNCSolution add-on, the following config vars are available in your app:

Variable Description
DNC_CLIENT_SECRET Used to secure the test plan endpoints
DNC_URL QuickCheck URL including ApplicationID and AuthProfileID
#Mock Example
$ DNC_CLIENT_SECRET:  a0**********-48**-90**-c***********
$ DNC_URL:  https://dnc-for-heroku-dev-*********.herokuapp.com/{AppID}/QuickCheck/{AuthProfileID}

AuthProfileID: The AuthProfileID is a required, unique numerical identifier used by DNCSolution to determine the scrub parameters for your phone number checks. When you upgrade to a Custom plan, a new AuthProfileID is provided, linking your account to the extended set of DNCSolution features included in your plan.

 

For authorization, add the client secret as a bearer token using the Authorization HTTP header.

Use the following commands to verify your config vars:

$ heroku config:get DNC_URL --app YOUR_HEROKU_APP_NAME
$ heroku config:get DNC_CLIENT_SECRET --app YOUR_HEROKU_APP_NAME

After the installation is complete, your application is configured to integrate with the add-on.

Local Setup

This add-on doesn’t require a local executable. It is self-contained and fully provisioned via Heroku.

Dashboard

The DNCSolution add-on dashboard shows the name and credentials needed to provision the add-on. Integration is handled through configuration variables and the API endpoint.

Access via CLI

$ heroku addons:open dnc
Opening dnc for YOUR_HEROKU_APP_NAME
$ heroku addons:info dnc --app YOUR_HEROKU_APP_NAME
=== dnc-infinite-62215
Attachments:  dnc-for-salesforce-dev::DNC
Installed at: Mon Oct 27 2025 18:10:26 GMT-0500 (CDT)
Max Price: free
Owning app: dnc-for-salesforce-dev
Plan: dnc:test
Price: free
State: created

Alternatively, you can open the add-on via the Heroku Dashboard. Navigate to your application, then select DNCSolution from the Add-ons menu.

How It Works

When installed, the add-on exposes an API endpoint that allows DNC checks of up to 500 phone numbers in a single request.

The POST method accepts a JSON payload containing a single required field: PhoneNumber.

Although LastEBRDate and LastRNDDate fields are visible in the request schema, they are not supported under this plan and should not be included in the request. Refer to the Request Body Parameters section for details.

Integration Example: Authentication and Basic API Call in C#

using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using System.Collections.Generic;

namespace QuickCheckClient
{
    public class QuickCheckRequest
    {
        public string PhoneNumber { get; set; } = ""
    }

    class Program
    {
        static async Task Main(string[] args)
        {
            var clientSecret = "****************";
            var appId= "*********************";
            var authProfileId = 12345;
            using var client = new HttpClient
            {
                BaseAddress = new Uri("https://dnc-for-heroku-***********.herokuapp.com")
            };

            // Add Authorization header
            client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", clientSecret);

            var request = new QuickCheckRequest
            {
                PhoneNumber = "7705555555"
            };

            List<QuickCheckRequest> requestList = new List<QuickCheckRequest>();
            requestList.Add(request);

            var options = new JsonSerializerOptions { PropertyNamingPolicy = null };
            var json = JsonSerializer.Serialize(requestList, options);
            var content = new StringContent(json, Encoding.UTF8, "application/json");

            try
            {
                var response = await client.PostAsync($"/{appId}/QuickCheck/{authProfileId}", content);
                var responseBody = await response.Content.ReadAsStringAsync();
                Console.WriteLine("Response:");
                Console.WriteLine(responseBody);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error: {ex.Message}");
            }
        }
    }
}

Request Body Parameters

Parameter Type Required Description Supported
PhoneNumber string or array Yes List of phone numbers to check. Each number must contain exactly 10 digits, can include dashes, and can’t start with 0 or 1. Yes

For plans that include Established Business Relationship verification:

Parameter Type Required Description Supported
LastEBRDate string (date) No Optional date used to identify Established Business Relationship (EBR) exemptions. Returns a GoodThruDate for the best exemption found. If not provided, the stored EBR date is used, if available. No
LastRNDDate string (date) No Date consent was obtained. Used for querying the Reassigned Numbers Database (RND). No

LastEBRDate and LastRNDDate aren’t supported in the Dev plan. You can omit them.

Sample Request Body

[
    {
        "PhoneNumber": "5099999999"
    },
    {
        "PhoneNumber": "5099996099"
    }
]

Response Body Parameters

The QuickCheck response delivers a structured, detailed summary of the callable status for each phone number in your request. It includes several sections, presented as separate tables, to help you understand why a number is callable or not and to identify any DNC filters that caused a number to return a “DNC” status. The response also includes call-curfew information. If the current time falls outside the allowable calling window, the number returns a “DNC” status.

The response body parameters are categorized here into multiple tables, providing a structured view of the results for each phone number. Developers can quickly determine why a number is callable or not, see the list of DNC filters on which the number was found, and review any limitations or calling time restrictions.

Metadata

Summarizes how many phone numbers successfully processed SuccessCount and how many were flagged as exceptions ExceptionCount.

Field Name Type Description Supported
SuccessCount integer (int32) Number of records successfully processed. Yes
ExceptionCount integer (int32) Number of records flagged as exceptions and unprocessed due to errors. Yes

QuickCheckResults

Contains detailed results for each phone number, including CallCurfewWindow, Filters, and the overall DNC status flag, Status.

Field Name Type Description Supported
QuickCheckResults array List of results for each phone number checked. Yes

CallCurfewWindow

Each result in the QuickCheckResults array contains a CallCurfewWindow object. This object contains the allowed calling hours and whether the number is currently within the call window.

Field Name Type Description Supported
CallCurfewWindow object Contains call curfew window information for the number. Yes
Start string Start time in 24-hour format (HH:mm), for example, 09:00, empty if call curfew was unchecked. Yes
End string End time in 24-hour format (HH:mm), for example, 21:00, empty if call curfew was unchecked. Yes
WithinCallWindow string YES if within call window, NO if outside, empty if call curfew unchecked. Yes

Filters

Each result in the QuickCheckResults array contains a Filters array. It lists any DNC filters that flagged the number, including wireless or state-specific lists.

A filter is a list of phone numbers used during a DNC check to determine a number’s callability status. For example, Wireless Filter is a list used by DNCSolution to identify if a number is wireless.

Field Name Type Description Supported
Filters array Array of FilterInfo objects applied to the phone number. Can be empty if no filters matched. Yes
FilterName string Name of the filter. Yes
Flag string Filter code of the filter. A three-character identifier representing the specific list on which a number matched. For example, a number found on the Wireless Filter has a flag of WIR. Yes
ListDate string Date the number was added to the filter. Yes
CustomerDate string Customer-supplied date for this filter/phone number combination. Yes
CustomerName string Name of the individual associated with the phone number. Yes

Phone Number Details

Each result in the QuickCheckResults array contains details for that phone number like their DNC status.

Field Name Type Description Supported
PhoneNumber string Phone number checked. Yes
IsWireless boolean true for wireless phone numbers, otherwise false. Yes
StateOfResidence string State used for call curfew and EBR processing. Used for call curfew and DNC filtering. Yes
LastEBRDate string Date used for EBR processing, included only if specified in the request. No
LastRNDDate string Date used for RND processing, included only if specified in the request. No
Status string Returns "DNC" if found on a DNC list, empty if not. If not on the DNC list, but the number is in a state where a state of emergency is declared, it returns “SOE”. Else if the number is in a state currently on a state holiday, it returns “HOL”. Yes
UTCOffset string UTC timezone offset of the location called. Yes
RNDStatus string Phone number status as determined by the Reassigned Numbers Database (RND). No

Sample Response Body

{
    "SuccessCount": 2,
    "ExceptionCount": 0,
    "QuickCheckResults": [
        {
            "CallCurfewWindow": {
                "Start": "0800",
                "End": "1400",
                "WithinCallWindow": "YES"
            },
            "Filters": [],
            "PhoneNumber": "5099996099",
            "IsWireless": false,
            "StateOfResidence": "Alabama (US)",
            "Status": "",
            "UTCOffset": "-5"
        },
        {
            "CallCurfewWindow": {
                "Start": "1000",
                "End": "1400",
                "WithinCallWindow": "NO"
            },
            "Filters": [
                {
                    "ListDate": "2019-02-15T21:45:00Z",
                    "CustomerDate": "2019-02-16T04:59:00Z",
                    "CustomerName": "",
                    "FilterName": "Wireless",
                    "Flag": "WIR"
                }
            ],
            "PhoneNumber": "5099999999",
            "IsWireless": true,
            "StateOfResidence": "Washington (US)",
            "Status": "DNC",
            "UTCOffset": "-7"
        }
    ]
}

Understanding the QuickCheck Response

By breaking the response into sections, developers can easily parse and integrate the information into applications and workflows.

The sample response includes metadata summarizing how many numbers successfully processed and how many were flagged as exceptions.

{
  "SuccessCount": 2,
  "ExceptionCount": 0
}

The rest of the response is the QuickCheckResults array, contains detailed results for each phone number, including "CallCurfewWindow", "Filters", and the overall DNC Status flag "Status".

"QuickCheckResults": [ { ... } ]

First Result: Callable (5099996099)

You can interpret the first result in the QuickCheckResults array as:

  • CallCurfewWindow: 08:00–14:00, currently within call window (WithinCallWindow: YES)
  • Filters: None matched.
  • IsWireless: false, so a landline
  • StateOfResidence: Alabama (US)
  • Status: empty, so not on DNC list
  • UTCOffset: -5

At the time of the check, this landline number wasn’t found on any DNC lists, falls within the permitted call window, and you can contact it in compliance with DNC rules.

Second Result: Not Callable (5099999999)

  • CallCurfewWindow: 10:00–14:00, currently outside call window (WithinCallWindow: NO)
  • Filters: Three matched, including “Wireless,” “WASHINGTON 509 (National List broken up by state according to the area code of the phone number),” and “Washington Wireless”
  • IsWireless: true
  • StateOfResidence: Washington (US)
  • Status: DNC (on Do Not Contact list)
  • UTCOffset: -7

You can’t call this wireless number because it’s outside the permitted call window and is on one or more DNC lists. Developers must respect these restrictions to ensure compliance.

Monitoring

Display stats and the current state of DNCSolution via the CLI:

$ heroku dnc:command
example output

The DNCSolution add-on does not write any data to your application logs. You can monitor our operational status at status.possiblenow.com.

Migrating Between Plans

Application owners must carefully manage migration timing to ensure proper application function. Contact addonsupport@possiblenow.com for custom plan migration instructions. For enterprise plans, you must generate OAuth tokens using the DNC client_id and client_secret. The Possible Now support team supplies those values during the migration process.

Removing the Add-on

This action destroys all associated configuration and can’t be undone.

$ heroku addons:destroy dnc --app YOUR_HEROKU_APP_NAME
Removing dnc from YOUR_HEROKU_APP_NAME… done

Next Steps

After successfully deploying the add-on, you can enhance your compliance capabilities by upgrading to a higher plan. Higher-tier plans provide access to premium lists and advanced integration options, including:

  • Known Litigator List: Identify phone numbers associated with known litigators.
  • Bad Number Detector: Flag invalid or problematic numbers before calling.
  • Reassigned Numbers Database: Check numbers that have been recently reassigned to new owners.
  • Integration with Salesforce and Data Platforms: Incorporate compliance checks directly within Salesforce Core (Flows or Mobile), Data 360 (driving the Customer 360), and Agentforce for seamless workflow integration.

Troubleshooting, Support, and Feedback

If the endpoint is unresponsive:

  • Verify Configuration Variables: Check with heroku config to ensure all required configuration variables provisioned correctly. Misconfigured or missing variables are a common cause of endpoint failures.

  • Contact Technical Support: For assistance with the add-on or troubleshooting, email the Possible Now support team at: addonsupport@possiblenow.com

  • Provide Product Feedback: Share suggestions, feature requests, or general feedback with the Possible Now product team at: productfeedback@possiblenow.com

Learn More

Explore the full suite of features that DNCSolution offers on our website.

Keep Reading

  • Papertrail
  • Heroku Scheduler
  • Cron To Go Scheduler - Scheduler as a Service
  • Advanced Scheduler
  • Expedited WAF

Or explore the All Add-ons category.

Feedback

Log in to submit feedback.

Information & Support

  • Getting Started
  • Documentation
  • Changelog
  • Compliance Center
  • Training & Education
  • Blog
  • Support Channels
  • Status

Language Reference

  • Node.js
  • Ruby
  • Java
  • PHP
  • Python
  • Go
  • Scala
  • Clojure
  • .NET

Other Resources

  • Careers
  • Elements
  • Products
  • Pricing
  • RSS
    • Dev Center Articles
    • Dev Center Changelog
    • Heroku Blog
    • Heroku News Blog
    • Heroku Engineering Blog
  • Twitter
    • Dev Center Articles
    • Dev Center Changelog
    • Heroku
    • Heroku Status
  • Github
  • LinkedIn
  • © 2025 Salesforce, Inc. All rights reserved. Various trademarks held by their respective owners. Salesforce Tower, 415 Mission Street, 3rd Floor, San Francisco, CA 94105, United States
  • heroku.com
  • Legal
  • Terms of Service
  • Privacy Information
  • Responsible Disclosure
  • Trust
  • Contact
  • Cookie Preferences
  • Your Privacy Choices