let
  pagesize = 10000,
  #"Access token" = "**access token**",

  HasLimit = (url as text) as logical =>
    if Text.Contains(url, "?") then
      let
        queryIdx = Text.PositionOf(url, "?"),
        query = Text.Middle(url, queryIdx)
      in
        Text.Contains(query, "limit")
    else
      false,
  GetNextLink = (response as binary, optional offset as number) =>
    let
      stepSize = pagesize,
      json = Json.Document(response),
      newOffset = if offset <> null and offset > 0 then offset + stepSize else stepSize
    in
      if List.IsEmpty(json) then null else newOffset,

  CWContents = (url as text, optional offset as number, optional access_token as text) =>
    let
      access = if access_token <> null then access_token else #"Access token",
      query = if HasLimit(url) then [] else [limit = Number.ToText(pagesize)],
      queryWithOffset = if offset <> null and offset > 0 then Record.Combine({query, [offset=Number.ToText(offset)]}) else query,
      content = Web.Contents("https://uwomgevingnaam.clockwise.info/api/v2", [
        RelativePath=url,
        Query=queryWithOffset,
        Headers=[#"Accept" = "application/json",
                 #"Authorization" = "Bearer " & access]
      ]),
      newOffset = GetNextLink(content, offset),
      json = Json.Document(content),
      table = Table.FromList(json, Splitter.SplitByNothing())
    in
      if List.IsEmpty(json) then null else table meta [Next=newOffset],
  Table.GenerateByPage = (getNextPage as function) as table =>
    let
      listOfPages = List.Generate(
        () => getNextPage(null),
        (lastPage) => lastPage <> null,
        (lastPage) => getNextPage(lastPage)
      ),
      tableOfPages = Table.FromList(listOfPages, Splitter.SplitByNothing(), {"Column1"}),
      firstRow = tableOfPages{0}?
    in
      if(firstRow = null) then
        Table.FromRows({})
      else
        Value.ReplaceType(
          Table.ExpandTableColumn(tableOfPages, "Column1", Table.ColumnNames(firstRow[Column1])),
          Value.Type(firstRow[Column1])
        ),

  PagedTable = (url as text, optional access_token as text) => Table.GenerateByPage((previous) =>
    let
      next = if(previous <> null) then Value.Metadata(previous)[Next] else null,
      current = if (previous <> null and next = null) then null else CWContents(url, next, access_token),
      link = if(current <> null) then Value.Metadata(current)[Next] else null
    in current meta [Next=link]
  ),

  ParsedTable = (url as text, optional rename as record) =>
    let
      access_token = #"Access token",
      recordtable = if HasLimit(url) then CWContents(url, null, access_token) else PagedTable(url, access_token),
      fieldnames = Record.FieldNames(Table.Column(recordtable, "Column1"){0}),
      defaultName = if rename <> null then Record.FieldOrDefault(rename, "_", "") else "",
      newFieldnames = if rename <> null then List.Transform(fieldnames, (name) =>
        let
          defaultFieldname = defaultName & name
        in
          Record.FieldOrDefault(rename, name, defaultFieldname)
      ) else null,
      result = Table.ExpandRecordColumn(recordtable, "Column1", fieldnames, newFieldnames),
      id = if rename <> null then Record.FieldOrDefault(rename, "ID") else null
    in
      if id <> null then Table.AddKey(result, {id}, true) else result,

  GetTable = (url as text) => ParsedTable(url),

  Bron = GetTable("/report/flat/projects?params=hier")
in
  Bron


