diff --git a/src/server/service/RatingServiceSubmitNotify.js b/src/server/service/RatingServiceSubmitNotify.js
new file mode 100644
index 0000000..7a2c689
--- /dev/null
+++ b/src/server/service/RatingServiceSubmitNotify.js
@@ -0,0 +1,81 @@
+/**
+ * Notification on all submit
+ *
+ * Copyright (C) 2018 R-T Specialty, LLC.
+ *
+ * This file is part of liza.
+ *
+ * liza is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+'use strict';
+
+const { Trait } = require( 'easejs' );
+const DslRaterContext = require( '../rater/DslRaterContext' )
+const RatingService = require( './RatingService' );
+
+
+/**
+ * Triggers DataApi when no results are available
+ *
+ * This information is currently stored in `__prem_avail_count`. In the
+ * future, it may be worth accepting a parameter to configure this at
+ * runtime.
+ */
+module.exports = Trait( 'RatingServiceSubmitNotify' )
+ .extend( RatingService,
+{
+ /**
+ * DataApi to trigger
+ * @type {DataApi}
+ */
+ 'private _dapi': null,
+
+
+ /**
+ * Initialize mixin with DataApi to trigger
+ *
+ * @param {DataApi} dapi DataApi to trigger
+ */
+ __mixin( dapi )
+ {
+ this._dapi = dapi;
+ },
+
+
+ /**
+ * Trigger previously provided DataApi when no results are available
+ *
+ * Result count is determined by DATA.__prem_avail_count.
+ *
+ * @param {Object} data rating data returned
+ * @param {Array} actions actions to send to client
+ * @param {Program} program program used to perform rating
+ * @param {Quote} quote quote used for rating
+ *
+ * @return {undefined}
+ */
+ 'override protected postProcessRaterData'( data, actions, program, quote )
+ {
+ const quote_id = quote.getId();
+ const avail = ( data.__prem_avail_count || [ 0 ] )[ 0 ];
+
+ if ( avail === 0 )
+ {
+ this._dapi.request( { quote_id: quote_id }, () => {} );
+ }
+
+ this.__super( data, actions, program, quote );
+ },
+} );
diff --git a/test/server/service/RatingServiceSubmitNotifyTest.js b/test/server/service/RatingServiceSubmitNotifyTest.js
new file mode 100644
index 0000000..dc0605b
--- /dev/null
+++ b/test/server/service/RatingServiceSubmitNotifyTest.js
@@ -0,0 +1,115 @@
+/**
+ * Tests RatingServiceSubmitNotify
+ *
+ * Copyright (C) 2018 R-T Specialty, LLC.
+ *
+ * This file is part of the Liza Data Collection Framework.
+ *
+ * liza is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+'use strict'
+
+const { Class } = require( 'easejs' );
+const { expect } = require( 'chai' );
+
+
+const {
+ dapi: {
+ DataApi,
+ },
+ server: {
+ service: {
+ RatingServiceSubmitNotify: Sut,
+ RatingService,
+ },
+ },
+ test: {
+ server: {
+ service: {
+ RatingServiceStub,
+ },
+ },
+ },
+} = require( '../../../' );
+
+
+describe( 'RatingServiceSubmitNotify', () =>
+{
+ [
+ {
+ prem_avail_count: [ 0 ],
+ expected_request: true,
+ },
+ {
+ prem_avail_count: [ 2 ],
+ expected_request: false,
+ },
+ {
+ // this shouldn't happen; ignore all but first index
+ prem_avail_count: [ 2, 2 ],
+ expected_request: false,
+ },
+ ].forEach( ( { prem_avail_count, expected_request }, i ) =>
+ it( `sends request on post process if no premiums (#${i})`, done =>
+ {
+ const {
+ stub_rate_data,
+ logger,
+ server,
+ raters,
+ dao,
+ request,
+ response,
+ quote,
+ } = RatingServiceStub.getStubs();
+
+ const quote_id = 1234;
+ let requested = false;
+
+ const dapi = Class.implement( DataApi ).extend(
+ {
+ // warning: if an expectation fails, because of how
+ // RatingService handles errors, it will cause the test to
+ // _hang_ rather than throw the assertion error
+ request( data, callback )
+ {
+ expect( data ).to.deep.equal( { quote_id: quote_id } );
+
+ requested = true;
+ },
+ } )();
+
+ const sut = RatingService.use( Sut( dapi ) )(
+ logger, dao, server, raters
+ );
+
+ quote.getId = () => quote_id;
+
+ // one of the methods that is called by the supertype
+ let save_called = false;
+ dao.setWorksheets = () => save_called = true;
+
+ stub_rate_data.__prem_avail_count = prem_avail_count;
+
+ sut.request( request, response, quote, 'something', () =>
+ {
+ expect( requested ).to.equal( expected_request );
+ expect( save_called ).to.be.true;
+
+ done();
+ } );
+ } )
+ );
+} );