Output a table as well-formed, indented JSON I have a table dictionary and its structure is: 

create table dictionary
(
  id integer,
  first_level_key character varying(50),
  key_name character varying(50),
  key_value_en character varying(1000),
  key_value_fr character varying(1000)
);


I want to output this table as well-formed indented JSON. 

I have tried the following query:

COPY (select 
   (select row_to_json(_) from (select c.first_level_key) as _) as first_last,
   c.key_name,c.key_name_value_en
from
   dictionary as c) 
 TO '/tmp/label_en.json';


I got JSON output, but not in the correct format, as shown below.

{"first_level_key":"topheader"} screen  Screen Reader Access
{"first_level_key":"header"}    title 
{"first_level_key":"header"}    subtitle 
{"first_level_key":"nav"}   about   About


The output that I want is well-formed, indented JSON as shown below!

{
"topheader":{

        "screen":"Screen Reader Access"
        },
        "header":{
        "title":"title",
        "subtitle":"subtitletest"
        },
    "nav":{
        "about":"About"
}}
While rereading the documentation, I noticed that whereas the pretty_bool option for JSON doesn't have an indented option, there is a jsonb_pretty(from_json jsonb) function which does produce indented text (Returns from_json as indented JSON text.) which looked as if it is what you are looking for.

When you have a "normal" table (I used your DDL in the question as my template), what you have to do is first convert it to JSON using the ROW_TO_JSON function (documentation), but as discussed here and elsewhere, this only converts the table to JSON on a row-by-row basis. The JSONB_AGG function (docs here) aggregates values, including nulls, as a JSON array). 

The final piece of the puzzle is the JSONB_PRETTY (discussed above) function which takes the JSON produced and outputs indented JSON text using your original query as the inner loop of the query.

Fiddle available here (and all DDL and DML is at the bottom of this answer).

SELECT JSONB_PRETTY(JSONB_AGG(tab)) AS i_json FROM
(
  SELECT
  ( 
    SELECT ROW_TO_JSON(x) 
    FROM 
    (
      SELECT c.first_level_key) AS x
    ) AS first_last,
    c.key_name, c.key_value_en
  FROM
  dictionary AS c
) AS tab;


Sample output (entire table at end of this answer):

[
    {
        "key_name": "ttttttt",
        "first_last": {
            "first_level_key": "afasaffasa"
        },
        "key_value_en": "zxccc"
    },


I believe that this is (finally!) the correct answer!

When asking a question, please always provide your version - it can be very important for providing an answer.

DDL and DML (also on the fiddle):

Create table. Note that I used the TEXT datatype instead of VARCHAR(n) for reasons discussed here and here.

CREATE TABLE dictionary
(
  id INTEGER,
  first_level_key TEXT,
  key_name TEXT,
  key_value_en TEXT,
  key_value_fr TEXT
);


Populate it:

INSERT INTO dictionary 
VALUES 
(4, 'afasaffasa', 'ttttttt', 'zxccc', 'zzzzzzz'),
(4, 'afasawweww', 'rrrrrrr', 'zxccc', 'zzzzzzz'),
(4, 'afayyyyyyy', 'eeeeeee', 'zxccc', 'zzzzzzz'),
(4, 'xxxxxxxxxx', 'wwwwwww', 'zxccc', 'zzzzzzz'),
(4, 'mmmmmmmmmm', 'qqqqqqq', 'zxccc', 'zzzzzzz');


Run query:

SELECT JSONB_PRETTY(JSONB_AGG(tab)) AS i_json FROM
(
  SELECT
  ( 
    SELECT ROW_TO_JSON(x) 
    FROM 
    (
      SELECT c.first_level_key) AS x
    ) AS first_last,
    c.key_name, c.key_value_en
  FROM
  dictionary AS c
) AS tab;


Result:

i_json
[
    {
        "key_name": "ttttttt",
        "first_last": {
            "first_level_key": "afasaffasa"
        },
        "key_value_en": "zxccc"
    },
    {
        "key_name": "rrrrrrr",
        "first_last": {
            "first_level_key": "afasawweww"
        },
        "key_value_en": "zxccc"
    },
    {
        "key_name": "eeeeeee",
        "first_last": {
            "first_level_key": "afayyyyyyy"
        },
        "key_value_en": "zxccc"
    },
    {
        "key_name": "wwwwwww",
        "first_last": {
            "first_level_key": "xxxxxxxxxx"
        },
        "key_value_en": "zxccc"
    },
    {
        "key_name": "qqqqqqq",
        "first_last": {
            "first_level_key": "mmmmmmmmmm"
        },
        "key_value_en": "zxccc"
    }
]