diff --git a/src/libs/convert/educationDegreeEntity.js b/src/libs/convert/educationDegreeEntity.js
new file mode 100644
index 0000000000000000000000000000000000000000..e16ba13f906bb28a28d6e26a150353e084fa2947
--- /dev/null
+++ b/src/libs/convert/educationDegreeEntity.js
@@ -0,0 +1,32 @@
+/*
+Copyright (C) 2016 Centro de Computacao Cientifica e Software Livre
+Departamento de Informatica - Universidade Federal do Parana - C3SL/UFPR
+
+This file is part of simcaq-node.
+
+simcaq-node 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.
+
+simcaq-node 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 simcaq-node.  If not, see <https://www.gnu.org/licenses/>.
+*/
+
+module.exports = function educationDegreeEntity(id) {
+    switch (id) {
+        case 1:
+            return 'Ensino Fundamental';
+        case 2:
+            return 'Ensino Médio';
+        case 3:
+            return 'Graduação Com Licenciatura';
+        case 4:
+            return 'Graduação Sem Licenciatura';
+    }
+};
diff --git a/src/libs/convert/educationLevelBasic.js b/src/libs/convert/educationLevelBasic.js
index 3d166fe525019ab06f6ecbb59ede4e382ca57fa6..7c242b07072d8e51530677207c3f5c05a605f436 100644
--- a/src/libs/convert/educationLevelBasic.js
+++ b/src/libs/convert/educationLevelBasic.js
@@ -24,11 +24,11 @@ module.exports = function educationLevelBasic(id) {
         return 'Creche';
         case 2:
         return 'Pré-Escola';
-        case 4:
+        case 3:
         return 'Ensino Fundamental - anos iniciais';
-        case 5:
+        case 4:
         return 'Ensino Fundamental - anos finais';
-        case 6:
+        case 5:
         return 'Ensino Médio';
         default:
         return 'Não classificada';
diff --git a/src/libs/convert/totalDoc.js b/src/libs/convert/totalDoc.js
new file mode 100644
index 0000000000000000000000000000000000000000..09f947c834c9958e971949b67533044111171d19
--- /dev/null
+++ b/src/libs/convert/totalDoc.js
@@ -0,0 +1,23 @@
+/*
+Copyright (C) 2016 Centro de Computacao Cientifica e Software Livre
+Departamento de Informatica - Universidade Federal do Parana - C3SL/UFPR
+
+This file is part of simcaq-node.
+
+simcaq-node 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.
+
+simcaq-node 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 simcaq-node.  If not, see <https://www.gnu.org/licenses/>.
+*/
+
+module.exports = function totalDoc(id) {
+    return '';
+};
diff --git a/src/libs/middlewares/aggregateData.js b/src/libs/middlewares/aggregateData.js
index aaa1ede48ce37f977f11e45b38e5dd87d4f8f5e6..5acac9248580af983a586114c7196c4d9614940a 100644
--- a/src/libs/middlewares/aggregateData.js
+++ b/src/libs/middlewares/aggregateData.js
@@ -32,7 +32,10 @@ const convert = {
     gender_entity: 'gender',
     age_range_entity: 'ageRangeEntity',
     post_graduation_entity: 'postGraduationEntity',
-    contract_type_entity: 'contractType'
+    contract_type_entity: 'contractType',
+    total_doc: "totalDoc",
+    education_degree_entity: "educationDegreeEntity",
+    government_agreement: "governmentAgreement"
 }
 
 function aggregateData(req, res, next) {
@@ -58,7 +61,9 @@ function aggregateData(req, res, next) {
             'gender_entity',
             'age_range_entity',
             'post_graduation_entity',
-            'contract_type_entity'
+            'contract_type_entity',
+            'total_doc',
+            'education_degree_entity'
         ]
         let id;
         const fields = req.query.dims.split(',');
diff --git a/src/libs/middlewares/id2str.js b/src/libs/middlewares/id2str.js
index 078df393ba871ad00ad9d39baa1e5d4d3282aa21..f366d90a30c8d5c57955856040c78d610b3392b3 100644
--- a/src/libs/middlewares/id2str.js
+++ b/src/libs/middlewares/id2str.js
@@ -124,6 +124,8 @@ const educationLevelModEntitySeg = require(`${libs}/convert/educationLevelModEnt
 const educationLevelModEntityAgg = require(`${libs}/convert/educationLevelModEntityAgg`);
 const ageRangeEntity = require(`${libs}/convert/ageRangeEntity`);
 const postGraduationEntity = require(`${libs}/convert/postGraduationEntity`);
+const totalDoc = require(`${libs}/convert/totalDoc`);
+const educationDegreeEntity = require(`${libs}/convert/educationDegreeEntity`);
 
 const ids = {
     gender_id: gender,
@@ -240,7 +242,9 @@ const ids = {
     education_level_mod_entity_agg: educationLevelModEntityAgg,
     age_range_entity: ageRangeEntity,
     post_graduation_entity: postGraduationEntity,
-    special_education_entity: specialEducationEntity
+    special_education_entity: specialEducationEntity,
+    total_doc: totalDoc,
+    education_degree_entity: educationDegreeEntity
 };
 
 function transform(removeId=false) {
@@ -379,5 +383,7 @@ module.exports = {
     educationLevelModEntityAgg,
     ageRangeEntity,
     postGraduationEntity,
-    specialEducationEntity
+    specialEducationEntity,
+    totalDoc,
+    educationDegreeEntity
 };
diff --git a/src/libs/routes_v1/api.js b/src/libs/routes_v1/api.js
index 1abfe6f09b21ab4d707b7e32bbf94b001e543a0a..bffc8b5d0ff428652d958d41d521ad1992007b85 100644
--- a/src/libs/routes_v1/api.js
+++ b/src/libs/routes_v1/api.js
@@ -155,6 +155,8 @@ const federativeEntity = require(`${libs}/routes_v1/federativeEntity`);
 
 const email = require(`${libs}/routes_v1/email`);
 
+const uniLocalOfferAggregate = require(`${libs}/routes_v1/uniLocalOfferAggregate`)
+
 api.get('/', (req, res) => {
     res.json({ msg: 'SimCAQ API v1 is running' });
 });
@@ -220,6 +222,7 @@ api.use('/enrollmentAggregate', enrollmentAggregate);
 api.use('/employeesAggregate', employeesAggregate);
 api.use('/course_aggregate', courseAggregate);
 api.use('/federativeEntity', federativeEntity);
+api.use('/uni_offer_aggregate', uniLocalOfferAggregate);
 
 
 //Publication 
diff --git a/src/libs/routes_v1/courseAggregate.js b/src/libs/routes_v1/courseAggregate.js
index 01773c055dad610aa890a75ae9959ac1c5131e20..78ae89a71035adf992cdc43f1e8253fc5dbef575 100644
--- a/src/libs/routes_v1/courseAggregate.js
+++ b/src/libs/routes_v1/courseAggregate.js
@@ -253,7 +253,7 @@ rqf.addField({
     where: {
         relation: '=',
         type: 'integer',
-        field: 'tp_org_aca'
+        field: 'tp_org_acad'
     }
 }).addValue({
     name: 'academic_level',
@@ -316,7 +316,7 @@ rqf.addField({
         field: 'cod_cine_area_detalhada'
     }
 }).addValue({
-    name: 'university',
+    name: 'uni_offer_aggregate',
     table: 'ies_ens_superior',
     tableField: ['cod_ies', 'nome_ies'],
     resultField: ['university_id', 'university_name'],
diff --git a/src/libs/routes_v1/employeesAggregate.js b/src/libs/routes_v1/employeesAggregate.js
index ab5102ceb21e8e2d5297035cd4afa90ebbc191b4..9fc52918f559b719e57ac088fe5e064eccec01d8 100644
--- a/src/libs/routes_v1/employeesAggregate.js
+++ b/src/libs/routes_v1/employeesAggregate.js
@@ -302,6 +302,14 @@ employeesAggregateApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
         .order('escola.ano_censo')
         .where('escola.situacao_funcionamento_pareada = 1 and (escola.ensino_regular = 1 or escola.ensino_eja = 1 or escola.educacao_profissional = 1)');
     }
+    else if (req.query.dims && req.query.dims.includes('total_doc')) {
+        req.sql.from('escola')
+        .field('SUM(escola.qt_doc_bas)', 'total_doc_bas')
+        .field('escola.ano_censo', 'year')
+        .group('escola.ano_censo')
+        .order('escola.ano_censo')
+        .where('escola.situacao_funcionamento_pareada = 1 and (escola.ensino_regular = 1 or escola.ensino_eja = 1 or escola.educacao_profissional = 1)');
+    }
     else {
         req.sql.from('escola')
         .field('SUM(escola.qt_doc_bas)', 'total')
diff --git a/src/libs/routes_v1/enrollmentAggregate.js b/src/libs/routes_v1/enrollmentAggregate.js
index 08d55ddba8787ba9906a722ab2d6ca98e011e58f..bb4ef2bf84827af062262f3167a4fe68622d5fbc 100644
--- a/src/libs/routes_v1/enrollmentAggregate.js
+++ b/src/libs/routes_v1/enrollmentAggregate.js
@@ -70,7 +70,7 @@ enrollmentAggregateApp.get('/adm_dependency', (req, res, next) => {
 enrollmentAggregateApp.get('/adm_dependency_detailed', (req, res, next) => {
     req.result = []
 
-    for (let i = 1; i <= 9; i++) {
+    for (let i = 1; i <= 8; i++) {
         req.result.push({
             id: i, name: id2str.admDependencyPriv(i)
         });
@@ -78,6 +78,18 @@ enrollmentAggregateApp.get('/adm_dependency_detailed', (req, res, next) => {
     next();
 }, response('adm_dependency_detailed'));
 
+enrollmentAggregateApp.get('/government_agreement', (req, res, next) => {
+    req.result = []
+    
+    for(let i = 1; i <= 6; ++i) {
+        req.result.push({
+            id: i,
+            name: id2str.governmentAgreement(i)
+        });
+    };
+    next();
+}, response('government_agreement'));
+
 enrollmentAggregateApp.get('/education_level_mod_agg', (req, res, next) => {
     req.result = []
 
@@ -480,10 +492,21 @@ rqf.addField({
     table: 'escola',
     tableField: 'localizacao_diferenciada_par',
     resultField: 'diff_location_id',
+    where: {
+        relation: 'is not null',
+        type: 'integer',
+        field: 'localizacao_diferenciada_par',
+        value: 'null'
+    }
+}).addValue({
+    name: 'government_agreement',
+    table: 'escola',
+    tableField: 'dependencia_convenio_publico',
+    resultField: 'government_agreement_id',
     where: {
         relation: '=',
         type: 'integer',
-        field: 'localizacao_diferenciada_par'
+        field: 'dependencia_convenio_publico'
     }
 });
 
@@ -499,7 +522,8 @@ enrollmentAggregateApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
         .field('SUM(escola.qt_mat_bas_fem)', 'total_fem')
         .field('escola.ano_censo', 'year')
         .group('escola.ano_censo')
-        .order('escola.ano_censo');
+        .order('escola.ano_censo')
+        .where('escola.localizacao_diferenciada_par is not null');
     }
     else if (req.query.dims && req.query.dims.includes('age_range')) {
         req.sql.from('escola')
@@ -511,7 +535,8 @@ enrollmentAggregateApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
         .field('SUM(escola.qt_mat_bas_18_mais)', 'total_18_mais')
         .field('escola.ano_censo', 'year')
         .group('escola.ano_censo')
-        .order('escola.ano_censo');
+        .order('escola.ano_censo')
+        .where('escola.localizacao_diferenciada_par is not null')
     }
     else if (req.query.dims && req.query.dims.includes('ethnic_group')) {
         req.sql.from('escola')
@@ -523,7 +548,8 @@ enrollmentAggregateApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
         .field('SUM(escola.qt_mat_bas_indigena)', 'total_indigena')
         .field('escola.ano_censo', 'year')
         .group('escola.ano_censo')
-        .order('escola.ano_censo');
+        .order('escola.ano_censo')
+        .where('escola.localizacao_diferenciada_par is not null')
     }
     else if (req.query.dims && req.query.dims.includes('education_level_mod_agg')) {
         req.sql.from('escola')
@@ -539,7 +565,9 @@ enrollmentAggregateApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
         .field('SUM(escola.qt_mat_prof_agg)', 'total_prof')
         .field('escola.ano_censo', 'year')
         .group('escola.ano_censo')
-        .order('escola.ano_censo');
+        .order('escola.ano_censo')
+        .where('escola.localizacao_diferenciada_par is not null');
+
     }
     else if (req.query.dims && req.query.dims.includes('integral_time_agg')) {
         req.sql.from('turma,escola')
@@ -549,7 +577,7 @@ enrollmentAggregateApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
         .field('escola.ano_censo', 'year')
         .group('escola.ano_censo')
         .order('escola.ano_censo')
-        .where('turma.tipo_atendimento_id <= 2 and turma.escola_id = escola.id and turma.ano_censo = escola.ano_censo');
+        .where('turma.tipo_atendimento_id <= 2 and turma.escola_id = escola.id and turma.ano_censo = escola.ano_censo and escola.localizacao_diferenciada_par is not null');
     }
     else if (req.query.dims && req.query.dims.includes('period_agg')) {
         req.sql.from('turma,escola')
@@ -561,7 +589,7 @@ enrollmentAggregateApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
         .field('escola.ano_censo', 'year')
         .group('escola.ano_censo')
         .order('escola.ano_censo')
-        .where('turma.tipo_atendimento_id <= 2 and turma.escola_id = escola.id and turma.ano_censo = escola.ano_censo');
+        .where('turma.tipo_atendimento_id <= 2 and turma.escola_id = escola.id and turma.ano_censo = escola.ano_censo and escola.localizacao_diferenciada_par is not null');
     }
     else if (req.query.dims && req.query.dims.includes('modality_integral_time')) {
         req.sql.from('escola')
@@ -573,6 +601,7 @@ enrollmentAggregateApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
         .field('escola.ano_censo', 'year')
         .group('escola.ano_censo')
         .order('escola.ano_censo')
+        .where('escola.localizacao_diferenciada_par is not null');
     }
     else if (req.query.dims && req.query.dims.includes('special_education')) {
         req.sql.from('escola')
@@ -581,6 +610,7 @@ enrollmentAggregateApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
         .field('escola.ano_censo', 'year')
         .group('escola.ano_censo')
         .order('escola.ano_censo')
+        .where('escola.localizacao_diferenciada_par is not null');
     }
     else {
         req.sql.from('escola')
@@ -588,6 +618,7 @@ enrollmentAggregateApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
         .field('escola.ano_censo', 'year')
         .group('escola.ano_censo')
         .order('escola.ano_censo')
+        .where('escola.localizacao_diferenciada_par is not null');
     }
     next();
 }, query, aggregateData, id2str.transform(false), response('enrollment_aggregate'));
diff --git a/src/libs/routes_v1/federativeEntity.js b/src/libs/routes_v1/federativeEntity.js
index 0b0c2b5c8230709ed81bbbddfb7fbd38dfc73d11..661907c54256a9b8ef48c4d26401d01269251042 100644
--- a/src/libs/routes_v1/federativeEntity.js
+++ b/src/libs/routes_v1/federativeEntity.js
@@ -67,6 +67,17 @@ federativeEntityApp.get('/adm_dependency', (req, res, next) => {
     next();
 }, response('adm_dependency'));
 
+federativeEntityApp.get('/education_degree_entity', (req, res, next) => {
+    req.result = []
+
+    for (let i = 1; i <= 4; i++) {
+        req.result.push({
+            id: i, name: id2str.educationDegreeEntity(i)
+        });
+    }
+    next();
+}, response('education_degree_entity'));
+
 federativeEntityApp.get('/adm_dependency_detailed', (req, res, next) => {
     req.result = []
 
@@ -342,8 +353,8 @@ rqf.addField({
     },
     join: {
         primary: 'id',
-        foreign: 'municipio_id',
-        foreignTable: 'escola'
+        foreign: 'cod_mun',
+        foreignTable: 'docentes_sinopse'
     }
 }, 'dims').addValueToField({
     name: 'city',
@@ -357,8 +368,8 @@ rqf.addField({
     },
     join: {
         primary: 'id',
-        foreign: 'municipio_id',
-        foreignTable: 'escola'
+        foreign: 'cod_mun',
+        foreignTable: 'docentes_sinopse'
     }
 }, 'filter').addValueToField({
     name: 'school',
@@ -428,6 +439,42 @@ rqf.addField({
 });
 
 federativeEntityApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
+    let whereRule = '';
+    const filtersObject = {}
+
+    req.query.filter.split(',').forEach((filter) => {
+        let [key, value] = filter.split(':');
+        filtersObject[key] = Number(JSON.parse(value));
+    })
+
+    if (req.query.filter && req.query.filter.includes('city')) {
+        whereRule = 'docentes_sinopse.cod_mun = ' + filtersObject.city;
+    }
+    else if (req.query.filter && req.query.filter.includes('state')) {
+        whereRule = 'docentes_sinopse.cod_uf = ' + filtersObject.state + 
+            ((req.query.dims && req.query.dims.includes('city')) ? '' : ' AND docentes_sinopse.cod_mun = 0');
+    }
+    else if (req.query.filter && req.query.filter.includes('region')) {
+        whereRule = 'docentes_sinopse.cod_reg = ' + filtersObject.region + 
+            ((req.query.dims !== undefined && req.query.dims.includes('state')) 
+                ? ' AND docentes_sinopse.cod_mun = 0'
+                : (req.query.dims !== undefined && req.query.dims.includes('city')) 
+                    ? '' 
+                    : ' AND docentes_sinopse.cod_uf = 0');
+                
+    }
+    else {
+        whereRule = (req.query.dims && req.query.dims.includes('region')) 
+            ? 'docentes_sinopse.cod_uf = 0'
+            : (req.query.dims && req.query.dims.includes('state'))
+                ? 'docentes_sinopse.cod_mun = 0' 
+                : (req.query.dims && req.query.dims.includes('city'))
+                    ? ''
+                    : 'docentes_sinopse.cod_reg = 0'
+                
+    }
+
+    console.log(whereRule);
 
     if (req.query.dims && req.query.dims.includes('education_level_mod_entity_seg'))
     {
@@ -442,7 +489,7 @@ federativeEntityApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
         .field('docentes_sinopse.ano_censo', 'year')
         .group('docentes_sinopse.ano_censo')
         .order('docentes_sinopse.ano_censo')
-        .where('docentes_sinopse.cod_reg = 0');
+        .where(whereRule);
     }
     else if (req.query.dims && req.query.dims.includes('education_level_mod_entity_agg'))
     {
@@ -465,7 +512,7 @@ federativeEntityApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
         .field('docentes_sinopse.ano_censo', 'year')
         .group('docentes_sinopse.ano_censo')
         .order('docentes_sinopse.ano_censo')
-        .where('docentes_sinopse.cod_reg = 0');
+        .where(whereRule);
     }
     else if (req.query.dims && req.query.dims.includes('special_education_entity'))
     {
@@ -475,7 +522,7 @@ federativeEntityApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
         .field('docentes_sinopse.ano_censo', 'year')
         .group('docentes_sinopse.ano_censo')
         .order('docentes_sinopse.ano_censo')
-        .where('docentes_sinopse.cod_reg = 0');
+        .where(whereRule);
     }
     else if (req.query.dims && req.query.dims.includes('adm_dependency_entity_agg'))
     {
@@ -485,7 +532,7 @@ federativeEntityApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
         .field('docentes_sinopse.ano_censo', 'year')
         .group('docentes_sinopse.ano_censo')
         .order('docentes_sinopse.ano_censo')
-        .where('docentes_sinopse.cod_reg = 0');
+        .where(whereRule);
     }
     else if (req.query.dims && req.query.dims.includes('adm_dependency_entity'))
     {
@@ -497,8 +544,20 @@ federativeEntityApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
         .field('docentes_sinopse.ano_censo', 'year')
         .group('docentes_sinopse.ano_censo')
         .order('docentes_sinopse.ano_censo')
-        .where('docentes_sinopse.cod_reg = 0');
+        .where(whereRule);
     }
+    else if (req.query.dims && req.query.dims.includes('education_degree_entity'))
+        {
+            req.sql.from('docentes_sinopse')
+            .field('SUM(docentes_sinopse.num_doc_esc_en_fund)', 'total_num_doc_esc_en_fund')
+            .field('SUM(docentes_sinopse.num_doc_esc_en_medio)', 'total_num_doc_esc_en_medio')
+            .field('SUM(docentes_sinopse.num_doc_esc_grad_com_licenciatura)', 'total_num_doc_esc_grad_com_licenciatura')
+            .field('SUM(docentes_sinopse.num_doc_esc_grad_sem_licenciatura)', 'total_num_doc_esc_grad_sem_licenciatura')
+            .field('docentes_sinopse.ano_censo', 'year')
+            .group('docentes_sinopse.ano_censo')
+            .order('docentes_sinopse.ano_censo')
+            .where(whereRule);
+        }
     else if (req.query.dims && req.query.dims.includes('location_entity'))
     {
         req.sql.from('docentes_sinopse')
@@ -507,7 +566,7 @@ federativeEntityApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
         .field('docentes_sinopse.ano_censo', 'year')
         .group('docentes_sinopse.ano_censo')
         .order('docentes_sinopse.ano_censo')
-        .where('docentes_sinopse.cod_reg = 0');
+        .where(whereRule);
     }
     else if (req.query.dims && req.query.dims.includes('gender_entity'))
     {
@@ -517,7 +576,7 @@ federativeEntityApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
         .field('docentes_sinopse.ano_censo', 'year')
         .group('docentes_sinopse.ano_censo')
         .order('docentes_sinopse.ano_censo')
-        .where('docentes_sinopse.cod_reg = 0');
+        .where(whereRule);
     }
     else if (req.query.dims && req.query.dims.includes('age_range_entity'))
     {
@@ -532,7 +591,7 @@ federativeEntityApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
         .field('docentes_sinopse.ano_censo', 'year')
         .group('docentes_sinopse.ano_censo')
         .order('docentes_sinopse.ano_censo')
-        .where('docentes_sinopse.cod_reg = 0');
+        .where(whereRule);
     }
     else if (req.query.dims && req.query.dims.includes('post_graduation_entity'))
     {
@@ -543,7 +602,7 @@ federativeEntityApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
         .field('docentes_sinopse.ano_censo', 'year')
         .group('docentes_sinopse.ano_censo')
         .order('docentes_sinopse.ano_censo')
-        .where('docentes_sinopse.cod_reg = 0');
+        .where(whereRule);
     }
     else if (req.query.dims && req.query.dims.includes('contract_type_entity'))
     {
@@ -555,7 +614,7 @@ federativeEntityApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
             .field('docentes_sinopse.ano_censo', 'year')
             .group('docentes_sinopse.ano_censo')
             .order('docentes_sinopse.ano_censo')
-            .where('docentes_sinopse.cod_reg = 0');
+            .where(whereRule);
     }
     else if ((req.query.dims && req.query.dims.includes('state')) || (req.query.filter && req.query.filter.includes('state'))) {
         req.sql.from('docentes_sinopse')
@@ -563,7 +622,7 @@ federativeEntityApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
         .field('docentes_sinopse.ano_censo', 'year')
         .group('docentes_sinopse.ano_censo')
         .order('docentes_sinopse.ano_censo')
-        .where('docentes_sinopse.cod_mun = 0');
+        .where(whereRule);
     }
     else if ((req.query.dims && req.query.dims.includes('region')) || (req.query.filter && req.query.filter.includes('region'))) {
         req.sql.from('docentes_sinopse')
@@ -571,7 +630,7 @@ federativeEntityApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
         .field('docentes_sinopse.ano_censo', 'year')
         .group('docentes_sinopse.ano_censo')
         .order('docentes_sinopse.ano_censo')
-        .where('docentes_sinopse.cod_uf = 0');
+        .where(whereRule);
     }
     else {
         req.sql.from('docentes_sinopse')
@@ -579,7 +638,7 @@ federativeEntityApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
         .field('docentes_sinopse.ano_censo', 'year')
         .group('docentes_sinopse.ano_censo')
         .order('docentes_sinopse.ano_censo')
-        .where('docentes_sinopse.cod_reg = 0');
+        .where(whereRule);
     }
     next();
 }, query, aggregateData, id2str.transform(false), response('federative_entity'));
diff --git a/src/libs/routes_v1/uniLocalOfferAggregate.js b/src/libs/routes_v1/uniLocalOfferAggregate.js
new file mode 100644
index 0000000000000000000000000000000000000000..f50afff10d25cb8e73f9399dfef810795ad01bc1
--- /dev/null
+++ b/src/libs/routes_v1/uniLocalOfferAggregate.js
@@ -0,0 +1,124 @@
+/*
+Copyright (C) 2024 Centro de Computacao Cientifica e Software Livre
+Departamento de Informatica - Universidade Federal do Parana - C3SL/UFPR
+
+This file is part of simcaq-node.
+
+simcaq-node 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.
+
+simcaq-node 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 simcaq-node.  If not, see <https://www.gnu.org/licenses/>.
+*/
+
+const express = require('express');
+
+const uniLocalOfferAggregateApp = express.Router();
+
+const libs = `${process.cwd()}/libs`;
+
+const query = require(`${libs}/middlewares/query`).query;
+
+const response = require(`${libs}/middlewares/response`);
+
+const ReqQueryFields = require(`${libs}/middlewares/reqQueryFields`);
+
+const config = require(`${libs}/config`); 
+
+const cache = require('apicache').options({ debug: config.debug, statusCodes: {include: [200]} }).middleware;
+
+let rqf = new ReqQueryFields();
+
+uniLocalOfferAggregateApp.use(cache('15 day'));
+
+rqf.addField({
+    name: 'filter',
+    field: false,
+    where: true
+}).addField({
+    name: 'dims',
+    field: true,
+    where: false
+}).addValue({
+    name: 'min_year',
+    table: 'curso_superior_agregado',
+    tableField: 'ano_censo',
+    resultField: 'year',
+    where: {
+        relation: '>=',
+        type: 'integer',
+        field: 'ano_censo'
+    }
+}).addValue({
+    name: 'max_year',
+    table: 'curso_superior_agregado',
+    tableField: '',
+    resultField: 'year',
+    where: {
+        relation: '<=',
+        type: 'integer',
+        field: 'ano_censo'
+    }
+}).addValue({
+    name: 'region',
+    table: 'curso_superior_agregado',
+    tableField: 'cod_reg',
+    resultField: 'region_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'cod_reg'
+    }
+}).addValue({
+    name: 'state',
+    table: 'estado',
+    tableField: ['id', 'nome'],
+    resultField: ['state_id', 'state_nome'],
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'id',
+    },
+    join: {
+        primary: 'id',
+        foreign: 'cod_uf',
+        foreignTable: 'curso_superior_agregado'
+    }
+}).addValue({
+    name: 'city',
+    table: 'municipio',
+    tableField: ['id', 'nome'],
+    resultField: ['city_id', 'city_name'],
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'id',
+        table: 'municipio'
+    },
+    join: {
+        primary: 'id',
+        foreign: 'cod_mun',
+        foreignTable: 'curso_superior_agregado'
+    }
+});
+
+uniLocalOfferAggregateApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
+    req.sql.from('curso_superior_agregado')
+    .field('DISTINCT curso_superior_agregado.cod_ies', 'id')
+    .field('ies_ens_superior.nome_ies', 'name')
+    .field('curso_superior_agregado.cod_mun', 'city_id')
+    .field('curso_superior_agregado.cod_uf', 'state_id')
+    .field('curso_superior_agregado.cod_reg', 'region_id')
+    .join('ies_ens_superior', null, 'curso_superior_agregado.cod_ies = ies_ens_superior.cod_ies and curso_superior_agregado.ano_censo = ies_ens_superior.ano_censo')
+    .order('curso_superior_agregado.cod_ies')
+    next();
+}, query, response('uni_offer_aggregate'));
+
+module.exports = uniLocalOfferAggregateApp;
\ No newline at end of file