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

# Read the plan for a date range

> Returns every date from `from` to `to`, empty days included, so a calendar renders
straight off the response. The default window is today through the next six days.

The range is capped at 62 days. Read a month at a time; there is no cursor,
because a date range is already a bounded read.

Both dates are local Istanbul dates. The planner has no instants: a block is on a day
at a wall-clock time, which is what the student sees and what survives a device with
the wrong timezone.



## OpenAPI

````yaml /api-reference/openapi.json get /api/plan
openapi: 3.1.0
info:
  title: Lala Client API
  description: >-
    The HTTP API behind Lala, the AI study companion for Turkish YKS and LGS
    students. This document is generated from the Zod schemas that validate each
    request at runtime. Do not hand-edit openapi.json. Student-visible text is
    Turkish. All identifiers are English.
  version: 1.0.0
servers:
  - url: https://client-api.lala.ist
    description: production
  - url: http://localhost:3000
    description: local dev
security:
  - supabaseJwt: []
tags:
  - name: chat
    description: The chat stream, the message history, and reactions
  - name: media
    description: Upload and read message attachments
  - name: plan
    description: The study planner — blocks of work on a day
  - name: journey
    description: Deneme results, topic performance, study-hours stats, and the streak
  - name: profile
    description: The student profile and onboarding
  - name: devices
    description: Push notification devices
  - name: system
    description: Health check
paths:
  /api/plan:
    get:
      tags:
        - plan
      summary: Read the plan for a date range
      description: >-
        Returns every date from `from` to `to`, empty days included, so a
        calendar renders

        straight off the response. The default window is today through the next
        six days.


        The range is capped at 62 days. Read a month at a time; there is no
        cursor,

        because a date range is already a bounded read.


        Both dates are local Istanbul dates. The planner has no instants: a
        block is on a day

        at a wall-clock time, which is what the student sees and what survives a
        device with

        the wrong timezone.
      operationId: getApiPlan
      parameters:
        - in: query
          name: from
          schema:
            type: string
          description: Local Istanbul calendar date, `YYYY-MM-DD`. Defaults to today.
        - in: query
          name: to
          schema:
            type: string
          description: >-
            Local Istanbul calendar date, `YYYY-MM-DD`. Defaults to `from` + 6
            days.
      responses:
        '200':
          description: The plan, by day
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PlanResponse'
        '400':
          description: The block or the range is not valid
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: The token is missing, expired, or invalid
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
components:
  schemas:
    PlanResponse:
      type: object
      properties:
        from:
          type: string
        to:
          type: string
        days:
          type: array
          items:
            $ref: '#/components/schemas/PlanDay'
          description: Every date in the range, empty days included.
      required:
        - from
        - to
        - days
    ErrorResponse:
      type: object
      properties:
        error:
          type: string
        issues:
          description: >-
            Present only on a 400 raised by request validation, capped at 10
            entries. Every other error carries `error` alone.
          type: array
          items:
            $ref: '#/components/schemas/ValidationIssue'
      required:
        - error
      description: Error body. `error` is a short English string.
    PlanDay:
      type: object
      properties:
        date:
          type: string
          description: Local Istanbul calendar date, `YYYY-MM-DD`.
        blocks:
          type: array
          items:
            $ref: '#/components/schemas/PlanBlock'
          description: Timed blocks first, in time order, then the undecided ones.
        plannedMinutes:
          type: integer
          minimum: -9007199254740991
          maximum: 9007199254740991
        unscheduledCount:
          type: integer
          minimum: -9007199254740991
          maximum: 9007199254740991
        doneCount:
          type: integer
          minimum: -9007199254740991
          maximum: 9007199254740991
      required:
        - date
        - blocks
        - plannedMinutes
        - unscheduledCount
        - doneCount
    ValidationIssue:
      type: object
      properties:
        path:
          type: string
          description: Dotted path to the offending field, empty at the root.
        message:
          type: string
      required:
        - path
        - message
    PlanBlock:
      type: object
      properties:
        id:
          type: string
          format: uuid
          pattern: >-
            ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
        date:
          type: string
          description: Local Istanbul calendar date, `YYYY-MM-DD`.
        startTime:
          anyOf:
            - type: string
            - type: 'null'
          description: >-
            Local Istanbul wall clock, `HH:MM`. Null while the time is
            undecided.
        endTime:
          anyOf:
            - type: string
            - type: 'null'
          description: Derived from the start and the length. Null unless both are known.
        durationMin:
          anyOf:
            - type: integer
              minimum: -9007199254740991
              maximum: 9007199254740991
            - type: 'null'
        scheduled:
          type: boolean
          description: True when the block has a time, not only a date.
        subject:
          type: string
        topic:
          anyOf:
            - type: string
            - type: 'null'
          description: Free text. `türev`, `paragraf`, …
        activity:
          $ref: '#/components/schemas/PlanActivity'
        targetQuestions:
          anyOf:
            - type: integer
              minimum: -9007199254740991
              maximum: 9007199254740991
            - type: 'null'
        notes:
          anyOf:
            - type: string
            - type: 'null'
        status:
          $ref: '#/components/schemas/PlanStatus'
        doneQuestions:
          anyOf:
            - type: integer
              minimum: -9007199254740991
              maximum: 9007199254740991
            - type: 'null'
        completedAt:
          anyOf:
            - type: string
              format: date-time
              pattern: >-
                ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$
            - type: 'null'
          description: Server-set when the status becomes `done`. Read-only.
        createdBy:
          type: string
          enum:
            - student
            - lala
          description: Who added the block. `lala` when it came out of a chat.
        position:
          type: integer
          minimum: -9007199254740991
          maximum: 9007199254740991
          description: Manual order among the blocks of a day that have no time.
        createdAt:
          type: string
          format: date-time
          pattern: >-
            ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$
        updatedAt:
          type: string
          format: date-time
          pattern: >-
            ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$
      required:
        - id
        - date
        - startTime
        - endTime
        - durationMin
        - scheduled
        - subject
        - topic
        - activity
        - targetQuestions
        - notes
        - status
        - doneQuestions
        - completedAt
        - createdBy
        - position
        - createdAt
        - updatedAt
    PlanActivity:
      type: string
      enum:
        - questions
        - lesson
        - review
        - subject_mock
        - mock_exam
        - homework
        - reading
        - break
        - other
      description: >-
        What the block is. Turkish labels, in order: soru çözümü, konu anlatımı,
        tekrar, branş denemesi, deneme, ödev, okuma, mola, çalışma. On write,
        the Turkish name is accepted too (`soru çözümü`, `branş denemesi`, …).
    PlanStatus:
      type: string
      enum:
        - planned
        - done
        - skipped
  securitySchemes:
    supabaseJwt:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: 'Supabase access token: `Authorization: Bearer <token>`'

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.