> ## Documentation Index
> Fetch the complete documentation index at: https://developers.thinkout.io/llms.txt
> Use this file to discover all available pages before exploring further.

# List categories

> Returns the category tree flattened, in the order ThinkOut displays it: inflows
first, then outflows, and within each direction every root followed immediately by
its own children. Siblings follow `position`.

Reading the page top to bottom therefore gives the product's own category screen.
`direction` narrows to one of its two panels.
Rebuild the hierarchy with `parent_id`, and re-sort with `position` within each
`parent_id` if you need the order again after storing the rows.

The tree is exactly two levels deep. A category with a `parent_id` never has
children of its own, and both levels can appear on a transaction.

A child's `direction` and `activity` always match its root's.




## OpenAPI

````yaml /openapi/v1.yaml get /categories
openapi: 3.1.0
info:
  title: ThinkOut API
  version: '1.0'
  description: >
    Programmatic access to the data of a ThinkOut workspace.


    Every endpoint in version 1 is a `GET`. Lists share one response envelope,
    and page

    with a cursor wherever the list can grow.


    Version 1 changes additively. New endpoints, new optional parameters, new
    response

    fields and new enum values can appear at any time, so tolerate unknown
    fields and

    never treat an enum as a closed set.
  contact:
    name: ThinkOut developer support
    url: https://developers.thinkout.io/guides/support
servers:
  - url: https://api.thinkout.io/v1
security:
  - apiKey: []
tags:
  - name: Banks
    description: The workspace's bank connections and the state of each one.
  - name: Accounts
    description: Manual, bank-synced and delegated accounts with computed balances.
  - name: Transactions
    description: Booked and pending movements on the workspace's accounts.
  - name: Categories
    description: The workspace category tree, split by direction and business activity.
  - name: Counterparties
    description: Customers and suppliers that transactions and forecasts are attributed to.
  - name: Labels
    description: Free-form tags grouped by label type.
  - name: Forecasts
    description: Planned inflows and outflows and the transactions that realised them.
  - name: Reports
    description: >-
      Totals rather than rows. Summaries over transactions and forecasts, and
      the workspace's own saved cash flow views.
paths:
  /categories:
    get:
      tags:
        - Categories
      summary: List categories
      description: >
        Returns the category tree flattened, in the order ThinkOut displays it:
        inflows

        first, then outflows, and within each direction every root followed
        immediately by

        its own children. Siblings follow `position`.


        Reading the page top to bottom therefore gives the product's own
        category screen.

        `direction` narrows to one of its two panels.

        Rebuild the hierarchy with `parent_id`, and re-sort with `position`
        within each

        `parent_id` if you need the order again after storing the rows.


        The tree is exactly two levels deep. A category with a `parent_id` never
        has

        children of its own, and both levels can appear on a transaction.


        A child's `direction` and `activity` always match its root's.
      operationId: listCategories
      parameters:
        - $ref: '#/components/parameters/direction'
        - $ref: '#/components/parameters/limit'
        - $ref: '#/components/parameters/cursor'
      responses:
        '200':
          description: A page of categories.
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/List'
                  - type: object
                    properties:
                      data:
                        type: array
                        items:
                          $ref: '#/components/schemas/Category'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/RateLimited'
components:
  parameters:
    direction:
      name: direction
      in: query
      schema:
        $ref: '#/components/schemas/Direction'
    limit:
      name: limit
      in: query
      description: Page size.
      schema:
        type: integer
        minimum: 1
        maximum: 500
        default: 100
    cursor:
      name: cursor
      in: query
      description: Opaque token from the previous page's `next_cursor`.
      schema:
        type: string
  schemas:
    List:
      type: object
      required:
        - object
        - data
        - has_more
        - next_cursor
      properties:
        object:
          type: string
          const: list
        data:
          type: array
          items: {}
        has_more:
          type: boolean
          description: Whether another page exists.
        next_cursor:
          type:
            - string
            - 'null'
          description: Pass as `cursor` to fetch the next page. `null` on the last page.
    Category:
      type: object
      required:
        - object
        - id
        - name
        - code
        - direction
        - activity
        - parent_id
        - position
        - color
        - created_at
        - updated_at
      properties:
        object:
          type: string
          const: category
        id:
          type: string
          format: uuid
        name:
          type: string
          example: Telecom
        code:
          type:
            - string
            - 'null'
          description: >
            The category's identifier in the template this workspace was created
            from.

            `null` for a category someone created.


            Only `uncategorized_inflows` and `uncategorized_outflows` are worth
            branching

            on. They mark the two categories holding unclassified money, they
            exist in

            every workspace, and ThinkOut refuses to delete them. Every other
            code depends

            on which template was used.
          example: uncategorized_outflows
        direction:
          $ref: '#/components/schemas/Direction'
        activity:
          $ref: '#/components/schemas/Activity'
        parent_id:
          type:
            - string
            - 'null'
          format: uuid
          description: '`null` for top-level categories.'
        position:
          type: integer
          description: Order among siblings, as shown in ThinkOut.
        color:
          type:
            - string
            - 'null'
          description: Lowercase hex color as shown in ThinkOut.
          pattern: ^#[0-9a-f]{6}$
          example: '#1b7fe4'
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
      example:
        object: category
        id: 3b4c5d6e-7f80-4a1b-9c2d-3e4f5a6b7c8d
        name: Telecom
        code: null
        direction: outflow
        activity: operating
        parent_id: 6a7b8c9d-0e1f-4a2b-8c3d-4e5f6a7b8c9d
        position: 2
        color: '#1b7fe4'
        created_at: '2024-01-01T10:00:00Z'
        updated_at: '2024-01-01T10:00:00Z'
    Direction:
      type: string
      description: >
        Whether money comes in or goes out.


        On a transaction or a forecast it follows the sign of `amount` and can
        never

        disagree with it. It is present so that responses can be grouped and
        read without

        inspecting signs.
      enum:
        - inflow
        - outflow
    Activity:
      type: string
      description: Cash flow statement section the category belongs to.
      enum:
        - operating
        - investing
        - financing
    Error:
      type: object
      required:
        - error
      properties:
        error:
          type: object
          required:
            - type
            - code
            - message
            - param
            - request_id
          properties:
            type:
              type: string
              enum:
                - invalid_request
                - authentication
                - not_found
                - rate_limit
                - server
            code:
              type: string
              description: >
                Stable machine-readable reason. Branch on this, not on
                `message`.

                Report-specific codes are `too_many_groups`, `period_too_long`,

                `as_of_in_future` and `invalid_expand`.
            message:
              type: string
              description: Human-readable explanation. Wording may change.
            param:
              type:
                - string
                - 'null'
              description: The query or path parameter at fault, when there is one.
            request_id:
              type: string
              description: Quote this when contacting support.
  responses:
    BadRequest:
      description: A parameter is invalid.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              type: invalid_request
              code: invalid_parameter
              message: Parameter 'from' must be a date in YYYY-MM-DD format.
              param: from
              request_id: req_01J8ZT4Q7Y6M3K
    Unauthorized:
      description: The API key is missing, unknown or revoked.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              type: authentication
              code: unauthorized
              message: Invalid API key.
              param: null
              request_id: req_01J8ZT4Q7Y6M3K
    RateLimited:
      description: Too many requests. Wait for the number of seconds in `Retry-After`.
      headers:
        Retry-After:
          schema:
            type: integer
          description: Seconds to wait before retrying.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              type: rate_limit
              code: rate_limited
              message: Rate limit exceeded. Retry after 12 seconds.
              param: null
              request_id: req_01J8ZT4Q7Y6M3K
  securitySchemes:
    apiKey:
      type: http
      scheme: bearer
      description: >-
        A workspace API key created in ThinkOut settings. One key reads one
        workspace.

````