diff --git a/src/libs/routes/api.js b/src/libs/routes/api.js
index d39b0352acf124bbffd66aba66c3d5ab86b39848..d4bab1d8cba1d2811060fb6d8e73ceefe3c16286 100644
--- a/src/libs/routes/api.js
+++ b/src/libs/routes/api.js
@@ -82,6 +82,7 @@ const portalMecInep = require(`${libs}/routes/portalMecInep`);
 
 const enrollmentProjection = require(`${libs}/routes/enrollmentProjection`);
 
+const employees = require(`${libs}/routes/employees`);
 
 api.get('/', (req, res) => {
     res.json({ msg: 'SimCAQ API is running' });
@@ -126,5 +127,7 @@ api.use('/verify_teacher', verifyTeacher);
 api.use('/class_count', classCount);
 api.use('/portal_mec_inep', portalMecInep);
 api.use('/enrollment_projection', enrollmentProjection);
+api.use('/employees', employees);
+
 
 module.exports = api;
diff --git a/src/libs/routes/employees.js b/src/libs/routes/employees.js
new file mode 100644
index 0000000000000000000000000000000000000000..3ea894270c03d5a2cbb8a46b0f89d7a0d25fd32c
--- /dev/null
+++ b/src/libs/routes/employees.js
@@ -0,0 +1,506 @@
+const express = require('express');
+
+const employeesApp = express.Router();
+
+const libs = `${process.cwd()}/libs`;
+
+const log = require(`${libs}/log`)(module);
+
+const squel = require('squel');
+
+const query = require(`${libs}/middlewares/query`).query;
+
+const response = require(`${libs}/middlewares/response`);
+
+const ReqQueryFields = require(`${libs}/middlewares/reqQueryFields`);
+
+const id2str = require(`${libs}/middlewares/id2str`);
+
+const config = require(`${libs}/config`);
+
+const passport = require('passport');
+
+const addMissing = require(`${libs}/middlewares/addMissing`);
+
+const cache = require('apicache').options({ debug: config.debug, statusCodes: {include: [200]}  }).middleware;
+
+let rqfTeacher = new ReqQueryFields();
+
+let rqfSchool = new ReqQueryFields();
+
+
+employeesApp.use(cache('15 day'));
+
+// Returns a tuple of start and ending years of the complete enrollments dataset.
+employeesApp.get('/year_range', (req, res, next) => {
+    req.sql.from('docente')
+    .field('MIN(docente.ano_censo)', 'start_year')
+    .field('MAX(docente.ano_censo)', 'end_year');
+    next();
+}, query, response('range'));
+
+employeesApp.get('/years', (req, res, next) => {
+    req.sql.from('docente').
+    field('DISTINCT docente.ano_censo', 'year');
+    next();
+}, query, response('years'));
+
+employeesApp.get('/source', (req, res, next) => {
+    req.sql.from('fonte')
+    .field('fonte', 'source')
+    .where('tabela = \'docente\'');
+    next();
+}, query, response('source'));
+
+employeesApp.get('/adm_dependency_detailed', (req, res, next) => {
+    req.result = [];
+    for(let i = 1; i <= 6; ++i) {
+        req.result.push({
+            id: i,
+            name: id2str.admDependencyPriv(i)
+        });
+    };
+    next();
+}, response('adm_dependency_detailed'));
+
+employeesApp.get('/adm_dependency', (req, res, next) => {
+    req.result = [];
+    for(let i = 1; i <= 4; ++i) {
+        req.result.push({
+            id: i,
+            name: id2str.admDependency(i)
+        });
+    };
+    next();
+}, response('adm_dependency'));
+
+employeesApp.get('/location', (req, res, next) => {
+    req.result = [];
+    for(let i = 1; i <= 2; ++i) {
+        req.result.push({
+            id: i,
+            name: id2str.location(i)
+        });
+    };
+    next();
+}, response('location'));
+
+employeesApp.get('/rural_location', (req, res, next) => {
+    req.result = [
+        {id: 1, name: "Urbana"},
+        {id: 2, name: "Rural"},
+        {id: 3, name: "Rural - Área de assentamento"},
+        {id: 4, name: "Rural - Terra indígena"},
+        {id: 5, name: "Rural - Área remanescente de quilombos"},
+        {id: 6, name: "Rural - Unidade de uso sustentável"}
+    ];
+    next();
+}, response('rural_location'));
+
+rqfSchool.addField({
+    name: 'filter',
+    field: false,
+    where: true
+}).addField({
+    name: 'dims',
+    field: true,
+    where: false
+}).addValue({
+    name: 'adm_dependency',
+    table: '@',
+    tableField: 'dependencia_adm_id',
+    resultField: 'adm_dependency_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'dependencia_adm_id'
+    }
+}).addValue({
+    name: 'adm_dependency_detailed',
+    table: '@',
+    tableField: 'dependencia_adm_priv',
+    resultField: 'adm_dependency_detailed_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'dependencia_adm_priv'
+    }
+}).addValue({
+    name: 'region',
+    table: 'regiao',
+    tableField: 'nome',
+    resultField: 'region_name',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'id'
+    },
+    join: {
+        primary: 'id',
+        foreign: 'regiao_id',
+        foreignTable: '@'
+    }
+}).addValue({
+    name: 'state',
+    table: 'estado',
+    tableField: 'nome',
+    resultField: 'state_name',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'id'
+    },
+    join: {
+        primary: 'id',
+        foreign: 'estado_id',
+        foreignTable: '@'
+    }
+}).addValueToField({
+    name: 'city',
+    table: 'municipio',
+    tableField: ['nome', 'id'],
+    resultField: ['city_name', 'city_id'],
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'id'
+    },
+    join: {
+        primary: 'id',
+        foreign: 'municipio_id',
+        foreignTable: '@'
+    }
+}, 'dims').addValueToField({
+    name: 'city',
+    table: 'municipio',
+    tableField: 'nome',
+    resultField: 'city_name',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'id'
+    },
+    join: {
+        primary: 'id',
+        foreign: 'municipio_id',
+        foreignTable: '@'
+    }
+}, 'filter').addValueToField({
+    name: 'school',
+    table: 'escola',
+    tableField: ['nome_escola', 'id'],
+    resultField: ['school_name', 'school_id'],
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'id'
+    },
+}, 'dims').addValueToField({
+    name: 'school',
+    table: 'escola',
+    tableField: 'nome_escola',
+    resultField: 'school_name',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'id'
+    },
+}, 'filter').addValue({
+    name: 'location',
+    table: '@',
+    tableField: 'cod_localizacao',
+    resultField: 'location_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'cod_localizacao'
+    }
+}).addValue({
+    name: 'rural_location',
+    table: '@',
+    tableField: 'localidade_area_rural',
+    resultField: 'rural_location_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'localidade_area_rural'
+    }
+}).addValue({
+    name: 'min_year',
+    table: '@',
+    tableField: 'ano_censo',
+    resultField: 'year',
+    where: {
+        relation: '>=',
+        type: 'integer',
+        field: 'ano_censo'
+    }
+}).addValue({
+    name: 'max_year',
+    table: '@',
+    tableField: 'ano_censo',
+    resultField: 'year',
+    where: {
+        relation: '<=',
+        type: 'integer',
+        field: 'ano_censo'
+    }
+});
+
+rqfTeacher.addField({
+    name: 'filter',
+    field: false,
+    where: true
+}).addField({
+    name: 'dims',
+    field: true,
+    where: false
+}).addValue({
+    name: 'adm_dependency',
+    table: '@',
+    tableField: 'dependencia_adm_id',
+    resultField: 'adm_dependency_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'dependencia_adm_id'
+    }
+}).addValue({
+    name: 'adm_dependency_detailed',
+    table: '@',
+    tableField: 'dependencia_adm_priv',
+    resultField: 'adm_dependency_detailed_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'dependencia_adm_priv'
+    }
+}).addValue({
+    name: 'region',
+    table: 'regiao',
+    tableField: 'nome',
+    resultField: 'region_name',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'id'
+    },
+    join: {
+        primary: 'id',
+        foreign: 'regiao_id',
+        foreignTable: '@'
+    }
+}).addValue({
+    name: 'state',
+    table: 'estado',
+    tableField: 'nome',
+    resultField: 'state_name',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'id'
+    },
+    join: {
+        primary: 'id',
+        foreign: 'estado_id',
+        foreignTable: '@'
+    }
+}).addValueToField({
+    name: 'city',
+    table: 'municipio',
+    tableField: ['nome', 'id'],
+    resultField: ['city_name', 'city_id'],
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'id'
+    },
+    join: {
+        primary: 'id',
+        foreign: 'municipio_id',
+        foreignTable: '@'
+    }
+}, 'dims').addValueToField({
+    name: 'city',
+    table: 'municipio',
+    tableField: 'nome',
+    resultField: 'city_name',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'id'
+    },
+    join: {
+        primary: 'id',
+        foreign: 'municipio_id',
+        foreignTable: '@'
+    }
+}, 'filter').addValueToField({
+    name: 'school',
+    table: 'escola',
+    tableField: ['nome_escola', 'id'],
+    resultField: ['school_name', 'school_id'],
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'id'
+    },
+    join: {
+        primary: ['id','ano_censo'],
+        foreign: ['id','ano_censo'],
+        foreignTable: '@'
+    }
+}, 'dims').addValueToField({
+    name: 'school',
+    table: 'escola',
+    tableField: 'nome_escola',
+    resultField: 'school_name',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'id'
+    },
+    join: {
+        primary: ['id','ano_censo'],
+        foreign: ['id','ano_censo'],
+        foreignTable: '@'
+    }
+}, 'filter').addValue({
+    name: 'location',
+    table: '@',
+    tableField: 'cod_localizacao',
+    resultField: 'location_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'cod_localizacao'
+    }
+}).addValue({
+    name: 'rural_location',
+    table: '@',
+    tableField: 'localidade_area_rural',
+    resultField: 'rural_location_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'localidade_area_rural'
+    }
+}).addValue({
+    name: 'min_year',
+    table: '@',
+    tableField: 'ano_censo',
+    resultField: 'year',
+    where: {
+        relation: '>=',
+        type: 'integer',
+        field: 'ano_censo'
+    }
+}).addValue({
+    name: 'max_year',
+    table: '@',
+    tableField: 'ano_censo',
+    resultField: 'year',
+    where: {
+        relation: '<=',
+        type: 'integer',
+        field: 'ano_censo'
+    }
+});
+
+
+function matchQueries(queryTotal, queryPartial) {
+    let match = [];
+    queryTotal.forEach((result) => {
+        let newObj = {};
+        let keys = Object.keys(result);
+        keys.forEach((key) => {
+            newObj[key] = result[key];
+        });
+        let index = keys.indexOf('total');
+        if(index > -1) keys.splice(index, 1);
+        let objMatch = null;
+
+        for(let i = 0; i < queryPartial.length; ++i) {
+            let partial = queryPartial[i];
+            let foundMatch = true;
+            for(let j = 0; j < keys.length; ++j) {
+                let key = keys[j];
+                if(partial[key] !== result[key]) {
+                    foundMatch = false;
+                    break;
+                }
+            }
+            if(foundMatch) {
+                objMatch = partial;
+                break;
+            }
+        }
+
+        if(objMatch) {
+            newObj.total = result.total - objMatch.total;
+            newObj.total_employees = result.total;
+            newObj.total_teachers = objMatch.total
+            match.push(newObj);
+        }
+    });
+
+    return match;
+}
+
+employeesApp.get('/', rqfSchool.parse(), (req, res, next) => {
+    req.allEmployees = {}
+    req.allTeacher = {}
+
+    if ("school" in req.filter) {
+        req.sql.field('SUM(escola.num_funcionarios)', 'total')
+        .field("'Brasil'", 'name')
+        .field('escola.ano_censo', 'year')
+        .from('escola')
+        .group('escola.ano_censo')
+        .order('escola.ano_censo')
+        .where('(escola.situacao_de_funcionamento = 1) AND (escola.ensino_regular = 1 OR escola.ensino_eja = 1 OR escola.educacao_profissional = 1) AND (dependencia_adm_id = 2 OR dependencia_adm_id = 3 OR dependencia_adm_id = 4) AND (escola.id=' + req.filter.school + ')');
+        delete req.filter.school;
+        next();
+    } else {
+        req.sql.field('SUM(escola.num_funcionarios)', 'total')
+        .field("'Brasil'", 'name')
+        .field('escola.ano_censo', 'year')
+        .from('escola')
+        .group('escola.ano_censo')
+        .order('escola.ano_censo')
+        .where('(escola.situacao_de_funcionamento = 1) AND (escola.ensino_regular = 1 OR escola.ensino_eja = 1 OR escola.educacao_profissional = 1) AND (dependencia_adm_id = 2 OR dependencia_adm_id = 3 OR dependencia_adm_id = 4)');
+        next();
+    }
+}, rqfSchool.build(), query, rqfSchool.parse(), id2str.transform(), (req, res, next) => {
+
+    req.allEmployees = req.result;
+    req.resetSql();
+
+    if ("school" in req.filter) {
+        req.sql.field('SUM(docente_por_escola.total_professores)', 'total')
+        .field("'Brasil'", 'name')
+        .field('docente_por_escola.ano_censo', 'year')
+        .from('docente_por_escola')
+        .group('docente_por_escola.ano_censo')
+        .order('docente_por_escola.ano_censo')
+        .where('(docente_por_escola.dependencia_adm_id > 1) AND (docente_por_escola.id=' + req.filter.school + ')');
+    } else {
+        req.sql.field('SUM(docente_por_escola.total_professores)', 'total')
+        .field("'Brasil'", 'name')
+        .field('docente_por_escola.ano_censo', 'year')
+        .from('docente_por_escola')
+        .group('docente_por_escola.ano_censo')
+        .order('docente_por_escola.ano_censo')
+        .where('(docente_por_escola.dependencia_adm_id > 1)');
+    }
+    next();
+
+}, rqfSchool.build(), query,  id2str.transform(),  (req, res, next) => {
+
+    req.allTeacher = req.result;
+    let aux_employees = matchQueries(req.allEmployees, req.allTeacher);
+    req.result = aux_employees;
+    next();
+}, response('employees'));
+
+module.exports = employeesApp;