diff --git a/Gemfile.lock b/Gemfile.lock
index 5f79fbee974ea44a99a89b3bcad3247968b42d33..2dc79b46329e2f327e568ef3b5f724a1406f68b8 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -1,7 +1,7 @@
 PATH
   remote: .
   specs:
-    quby-compiler (0.3.4)
+    quby-compiler (0.3.5)
       actionview (>= 5.0)
       activemodel (>= 5.0)
       activesupport (>= 5.0)
@@ -21,8 +21,8 @@ GEM
       erubi (~> 1.4)
       rails-dom-testing (~> 2.0)
       rails-html-sanitizer (~> 1.1, >= 1.2.0)
-    active_interaction (3.8.3)
-      activemodel (>= 4, < 7)
+    active_interaction (4.0.2)
+      activemodel (>= 5, < 7)
     activemodel (6.0.4)
       activesupport (= 6.0.4)
     activerecord (6.0.4)
@@ -34,7 +34,7 @@ GEM
       minitest (~> 5.1)
       tzinfo (~> 1.1)
       zeitwerk (~> 2.2, >= 2.2.2)
-    appsignal (2.10.12)
+    appsignal (3.0.8)
       rack
     builder (3.2.4)
     coderay (1.1.3)
@@ -44,13 +44,13 @@ GEM
     dry-configurable (0.12.1)
       concurrent-ruby (~> 1.0)
       dry-core (~> 0.5, >= 0.5.0)
-    dry-container (0.7.2)
+    dry-container (0.8.0)
       concurrent-ruby (~> 1.0)
       dry-configurable (~> 0.1, >= 0.1.3)
-    dry-core (0.5.0)
+    dry-core (0.6.0)
       concurrent-ruby (~> 1.0)
     dry-inflector (0.2.0)
-    dry-logic (1.1.0)
+    dry-logic (1.2.0)
       concurrent-ruby (~> 1.0)
       dry-core (~> 0.5, >= 0.5)
     dry-struct (1.4.0)
@@ -91,10 +91,10 @@ GEM
       loofah (~> 2.3)
     rake (12.3.3)
     redcarpet (3.5.1)
-    roqua-support (0.3.5)
-      active_interaction (~> 3.0)
-      activesupport (>= 5.1, < 6.1)
-      appsignal (>= 2.9, < 2.11)
+    roqua-support (0.4.0)
+      active_interaction (>= 3.0, < 5.0)
+      activesupport (>= 5.2, < 6.2)
+      appsignal (>= 2.9, < 3.1)
       naught (~> 1.0)
       with_advisory_lock (~> 3.2)
     rspec (3.9.0)
diff --git a/lib/quby/compiler/entities/outcome_table.rb b/lib/quby/compiler/entities/outcome_table.rb
index 64d042e178f8e269ea4839bbd3acec183441820d..06654c0c9448cf077b93a2e3e6457664c41ab46f 100644
--- a/lib/quby/compiler/entities/outcome_table.rb
+++ b/lib/quby/compiler/entities/outcome_table.rb
@@ -15,6 +15,7 @@ module Quby
         validates :score_keys, :subscore_keys, :questionnaire, :key, presence: true
         validates :name, presence: true, if: proc { |table| table.default_collapsed }
         validate :references_existing_score_keys
+        validate :no_outcome_tables_defined_in_score_schemas
 
         def references_existing_score_keys
           (score_keys - questionnaire.score_schemas.values.map(&:key)).each do |missing_key|
@@ -25,6 +26,17 @@ module Quby
             errors.add :subscore_keys, "#{missing_key.inspect} not found in subscore schemas"
           end
         end
+
+        def no_outcome_tables_defined_in_score_schemas
+          if questionnaire.score_schemas.values.any? do |schema|
+            schema.subscore_schemas.any? do |subscore|
+              subscore.outcome_table != :main
+            end
+          end
+            errors.add :score_schemas,
+              "Outcome table associations defined in score schemas should not be combined with explicit outcome tables"
+          end
+        end
       end
     end
   end
diff --git a/lib/quby/compiler/outputs/roqua_serializer.rb b/lib/quby/compiler/outputs/roqua_serializer.rb
index bf0307256e68d302ccdeacb2ff728b1ce3509e5c..4ffc9002e0acc64b83ebb52e90fe048da48ef419 100644
--- a/lib/quby/compiler/outputs/roqua_serializer.rb
+++ b/lib/quby/compiler/outputs/roqua_serializer.rb
@@ -84,11 +84,47 @@ module Quby
         #   <subscore_key:Symbol>: <subscore.label:String> # headers for each subscore key for all tables.
 
         def outcome_tables_schema
+          if questionnaire.outcome_tables.present?
+            outcome_tables_from_definition
+          else
+            outcome_tables_from_score_schemas
+          end
+        end
+
+        def outcome_tables_from_definition
+          # hash of tables, with the score keys (rows) and subscore keys (columns) used for each
+          tables = {}
+          # hash of `subscore_key: subscore_label` pairs used in tables
+          headers = {}
+
+          questionnaire.outcome_tables.each do |table|
+            tables[table.key] = {name: table.name,
+                                 default_collapsed: table.default_collapsed,
+                                 score_keys: table.score_keys,
+                                 subscore_keys: table.subscore_keys}.compact
+
+            table.subscore_keys.each do |subscore_key|
+              table.score_keys.find do |score_key|
+                subschema = questionnaire.score_schemas[score_key].subscore_schemas.find do |subschema|
+                  subschema.key == subscore_key
+                end
+                headers[subscore_key] = subschema&.label
+              end
+            end
+          end
+
+          {
+            headers: headers,
+            tables: tables,
+          }
+        end
+
+        def outcome_tables_from_score_schemas
           # hash of tables, with the score keys (rows) and subscore keys (columns) used for each
           tables = Hash.new{ |hash, key| hash[key] = {score_keys: Set.new, subscore_keys: Set.new } }
           # hash of `subscore_key: subscore_label` pairs used in tables
           headers = {}
-          
+
           questionnaire.score_schemas.values.each do |schema|
             schema.subscore_schemas.each do |subschema|
               next if subschema.outcome_table.blank?
@@ -97,7 +133,7 @@ module Quby
               headers[subschema.key] = subschema.label
             end
           end
-          
+
           {
             headers: headers,
             tables: tables,
diff --git a/spec/quby/compiler/entities/outcome_table_spec.rb b/spec/quby/compiler/entities/outcome_table_spec.rb
index f87e919b79a58fe1b2ce001cdefbe86d7e63cefb..c2ef7e6b529194925e4d52a4883bf838505fc5e3 100644
--- a/spec/quby/compiler/entities/outcome_table_spec.rb
+++ b/spec/quby/compiler/entities/outcome_table_spec.rb
@@ -29,5 +29,25 @@ module Quby::Compiler::Entities
                                                   "Subscore keys :unknown_key_2 not found in subscore schemas"])
       end
     end
+
+    describe '#no_outcome_tables_defined_in_score_schemas' do
+      let(:questionnaire) do
+        Quby::Compiler::DSL.build("test") do
+          score(:key,
+                label: 'score',
+                schema: [{key: :value, label: 'Score', export_key: :key, outcome_table: :something}]) { {value: 'oh1'} }
+          score(:key2, label: 'score2', schema: [{key: :value, label: 'Score 2', export_key: :key2}]) { {value: 'oh2'} }
+        end
+      end
+      it 'checks all score schemas don\'t have a outcome table defined already' do
+        table = described_class.new(key: :test_outcome_table,
+                                    score_keys: %i[key key2],
+                                    subscore_keys: [:value],
+                                    questionnaire: questionnaire)
+        table.valid?
+        expect(table.errors.full_messages).to \
+         eq(["Score schemas Outcome table associations defined in score schemas should not be combined with explicit outcome tables"])
+      end
+    end
   end
 end
diff --git a/spec/quby/compiler/outputs/roqua_serializer_spec.rb b/spec/quby/compiler/outputs/roqua_serializer_spec.rb
index 47f0a85323230a8aba39d470f5930e27cfe47f9c..033c88c92f23b22f3b6191703d0e454f6a825ec4 100644
--- a/spec/quby/compiler/outputs/roqua_serializer_spec.rb
+++ b/spec/quby/compiler/outputs/roqua_serializer_spec.rb
@@ -1,7 +1,47 @@
 require 'spec_helper'
 
 describe Quby::Compiler::Outputs::RoquaSerializer do
-  it 'generates outcome schemas' do
+  it 'generates outcome tables schema from questionnaire defined outcome tables' do
+    questionnaire = dsl("test") do
+      title "Test Quest"
+
+      score_schema :score1, 'Score 1' do
+        subscore(:value, 'Waarde', export_key: :score1) { 1 }
+        subscore(:int, 'Interpretatie', export_key: :score1_i) { 'Wah' }
+      end
+
+      score_schema :score0, 'Score 0' do
+        subscore(:value, 'Nog iets', export_key: :score0) { 'Iets' }
+      end
+
+      outcome_table name: 'Alleen score 0',
+                    key: :only_score0,
+                    score_keys: [:score0],
+                    default_collapsed: true,
+                    subscore_keys: %i[value]
+
+      outcome_table name: 'Scores',
+                    key: :scores,
+                    score_keys: [:score0, :score1],
+                    subscore_keys: %i[value int]
+    end
+    serializer = described_class.new(questionnaire)
+
+    expected = {
+      outcome_tables_schema:
+        {headers: {int: "Interpretatie", value: "Nog iets"},
+         tables: {only_score0: {default_collapsed: true,
+                                name: "Alleen score 0",
+                                score_keys: [:score0],
+                                subscore_keys: [:value]},
+                  scores: {name: "Scores",
+                           score_keys: [:score0, :score1],
+                           subscore_keys: [:value, :int]}}}
+    }
+    expect(serializer.as_json).to include(expected)
+  end
+
+  it 'generates outcome tables schema from score schema outcome tables' do
     questionnaire = dsl("test") do
       title "Test Quest"
 
@@ -50,9 +90,9 @@ describe Quby::Compiler::Outputs::RoquaSerializer do
                 outcome_tables_schema: {
                   headers: {int: "Interpretatie", mean: "Gemiddelde", something: "Nog iets", value: "Waarde"},
                   tables: {
-                    main: {:score_keys => [:score0], :subscore_keys => [:something]},
-                    values: {:score_keys => [:score1, :score2], :subscore_keys => [:value, :int]},
-                    means: {:score_keys => [:score3, :score4], :subscore_keys => [:mean]}
+                    main: {score_keys: [:score0], subscore_keys: [:something]},
+                    values: {score_keys: [:score1, :score2], subscore_keys: [:value, :int]},
+                    means: {score_keys: [:score3, :score4], subscore_keys: [:mean]}
                   }
                 }
               })