How to select blocks from a result by condition?
A classical gaps-and-islands problem:

SELECT master_id, min(created_at) AS date_from, max(created_at) AS date_to
FROM  (
   SELECT *
        , count(*) FILTER (WHERE step) OVER (PARTITION BY master_id ORDER BY created_at) AS range
   FROM  (
      SELECT *, created_at &gt; lag(created_at) OVER (PARTITION BY master_id ORDER BY created_at) + interval '1 month' AS step
      FROM   tbl
      ) sub1
   ) sub2
GROUP  BY master_id, range
ORDER  BY master_id, range;


Related (with explanation):


Combining separate columns into smallest possible related ranges
Select longest continuous sequence
Calculate Difference in Overlapping Time in PostgreSQL / SSRS