{
  "openapi": "3.0.3",
  "info": {
    "title": "Sundial Habits Integrations",
    "version": "1.0.0",
    "description": "Read your server-synced habits and progress, and record check-ins."
  },
  "servers": [
    {
      "url": "https://api.sundialhabits.com"
    }
  ],
  "paths": {
    "/api/v1/connection": {
      "get": {
        "operationId": "get_connection",
        "summary": "Get Connected Account",
        "description": "Confirm the connected Sundial account, permissions, and key expiry. Reads only your account.",
        "tags": [
          "Habits"
        ],
        "security": [
          {
            "accessKey": []
          }
        ],
        "x-sundial-access": "read",
        "responses": {
          "200": {
            "description": "Confirmed result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "account": {
                      "type": "object",
                      "properties": {
                        "name": {
                          "type": "string"
                        },
                        "email": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "name",
                        "email"
                      ],
                      "additionalProperties": false
                    },
                    "access": {
                      "type": "string",
                      "enum": [
                        "read",
                        "checkins"
                      ]
                    },
                    "expiresAt": {
                      "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": [
                    "account",
                    "access",
                    "expiresAt"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "default": {
            "description": "The request failed. Read the stable error code before retrying.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        },
                        "requestID": {
                          "type": "string",
                          "format": "uuid",
                          "examples": [
                            "00000000-0000-4000-8000-000000000002"
                          ]
                        },
                        "retryable": {
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "requestID",
                        "retryable"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          }
        },
        "parameters": []
      }
    },
    "/api/v1/habits": {
      "get": {
        "operationId": "list_habits",
        "summary": "List Habits",
        "description": "Read your habits, including private habits, schedules, and check-in state for a calendar day. Results reflect server-synced data.",
        "tags": [
          "Habits"
        ],
        "security": [
          {
            "accessKey": []
          }
        ],
        "x-sundial-access": "read",
        "responses": {
          "200": {
            "description": "Confirmed result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "asOf": {
                      "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))$"
                    },
                    "habits": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid",
                            "examples": [
                              "00000000-0000-4000-8000-000000000002"
                            ]
                          },
                          "title": {
                            "type": "string"
                          },
                          "archived": {
                            "type": "boolean"
                          },
                          "position": {
                            "type": "number"
                          },
                          "schedule": {
                            "minItems": 1,
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "from": {
                                  "nullable": true,
                                  "type": "string",
                                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                                },
                                "rule": {
                                  "oneOf": [
                                    {
                                      "type": "object",
                                      "properties": {
                                        "kind": {
                                          "type": "string",
                                          "enum": [
                                            "daily"
                                          ]
                                        }
                                      },
                                      "required": [
                                        "kind"
                                      ],
                                      "additionalProperties": false
                                    },
                                    {
                                      "type": "object",
                                      "properties": {
                                        "kind": {
                                          "type": "string",
                                          "enum": [
                                            "weekdays"
                                          ]
                                        },
                                        "days": {
                                          "minItems": 1,
                                          "type": "array",
                                          "items": {
                                            "type": "integer",
                                            "minimum": 1,
                                            "maximum": 7
                                          }
                                        }
                                      },
                                      "required": [
                                        "kind",
                                        "days"
                                      ],
                                      "additionalProperties": false
                                    },
                                    {
                                      "type": "object",
                                      "properties": {
                                        "kind": {
                                          "type": "string",
                                          "enum": [
                                            "perWeek"
                                          ]
                                        },
                                        "times": {
                                          "type": "integer",
                                          "minimum": 1,
                                          "maximum": 7
                                        },
                                        "weekStart": {
                                          "type": "integer",
                                          "minimum": 1,
                                          "maximum": 7
                                        }
                                      },
                                      "required": [
                                        "kind",
                                        "times",
                                        "weekStart"
                                      ],
                                      "additionalProperties": false
                                    },
                                    {
                                      "type": "object",
                                      "properties": {
                                        "kind": {
                                          "type": "string",
                                          "enum": [
                                            "everyNDays"
                                          ]
                                        },
                                        "n": {
                                          "type": "integer",
                                          "minimum": 2,
                                          "maximum": 30
                                        }
                                      },
                                      "required": [
                                        "kind",
                                        "n"
                                      ],
                                      "additionalProperties": false
                                    }
                                  ]
                                }
                              },
                              "required": [
                                "from",
                                "rule"
                              ],
                              "additionalProperties": false
                            }
                          },
                          "reminder": {
                            "nullable": true,
                            "type": "object",
                            "properties": {
                              "hour": {
                                "type": "integer",
                                "minimum": 0,
                                "maximum": 23
                              },
                              "minute": {
                                "type": "integer",
                                "minimum": 0,
                                "maximum": 59
                              }
                            },
                            "required": [
                              "hour",
                              "minute"
                            ],
                            "additionalProperties": false
                          },
                          "visibility": {
                            "type": "string",
                            "enum": [
                              "friends",
                              "private"
                            ]
                          },
                          "revision": {
                            "type": "string",
                            "pattern": "^\\d+$",
                            "examples": [
                              "1"
                            ]
                          },
                          "due": {
                            "type": "boolean"
                          },
                          "checkIn": {
                            "type": "object",
                            "properties": {
                              "habitID": {
                                "type": "string",
                                "format": "uuid",
                                "examples": [
                                  "00000000-0000-4000-8000-000000000002"
                                ]
                              },
                              "day": {
                                "type": "string",
                                "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                                "examples": [
                                  "2026-10-20"
                                ]
                              },
                              "completed": {
                                "type": "boolean"
                              },
                              "timeZone": {
                                "type": "string",
                                "maxLength": 100,
                                "examples": [
                                  "America/Los_Angeles"
                                ]
                              },
                              "revision": {
                                "nullable": true,
                                "type": "string",
                                "pattern": "^\\d+$",
                                "examples": [
                                  "1"
                                ]
                              }
                            },
                            "required": [
                              "habitID",
                              "day",
                              "completed",
                              "timeZone",
                              "revision"
                            ],
                            "additionalProperties": false
                          }
                        },
                        "required": [
                          "id",
                          "title",
                          "archived",
                          "position",
                          "schedule",
                          "reminder",
                          "visibility",
                          "revision",
                          "due",
                          "checkIn"
                        ],
                        "additionalProperties": false
                      }
                    },
                    "nextCursor": {
                      "nullable": true,
                      "type": "string",
                      "format": "uuid",
                      "examples": [
                        "00000000-0000-4000-8000-000000000002"
                      ]
                    },
                    "onBreak": {
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "asOf",
                    "habits",
                    "nextCursor",
                    "onBreak"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "default": {
            "description": "The request failed. Read the stable error code before retrying.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        },
                        "requestID": {
                          "type": "string",
                          "format": "uuid",
                          "examples": [
                            "00000000-0000-4000-8000-000000000002"
                          ]
                        },
                        "retryable": {
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "requestID",
                        "retryable"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "day",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "examples": [
                "2026-10-20"
              ],
              "description": "Gregorian calendar date, YYYY-MM-DD, between 1900 and 2100."
            }
          },
          {
            "name": "timeZone",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 100,
              "examples": [
                "America/Los_Angeles"
              ],
              "description": "IANA time zone used to interpret today, such as America/Los_Angeles."
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": true,
            "schema": {
              "default": 50,
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid",
              "examples": [
                "00000000-0000-4000-8000-000000000002"
              ]
            }
          }
        ]
      }
    },
    "/api/v1/history": {
      "get": {
        "operationId": "get_history",
        "summary": "Get Check-in History",
        "description": "Read one habit’s recorded check-ins over up to 366 calendar days, including explicit undo records. Missing dates are incomplete. Results reflect server-synced data.",
        "tags": [
          "Habits"
        ],
        "security": [
          {
            "accessKey": []
          }
        ],
        "x-sundial-access": "read",
        "responses": {
          "200": {
            "description": "Confirmed result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "asOf": {
                      "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))$"
                    },
                    "checkIns": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "habitID": {
                            "type": "string",
                            "format": "uuid",
                            "examples": [
                              "00000000-0000-4000-8000-000000000002"
                            ]
                          },
                          "day": {
                            "type": "string",
                            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                            "examples": [
                              "2026-10-20"
                            ]
                          },
                          "completed": {
                            "type": "boolean"
                          },
                          "timeZone": {
                            "type": "string",
                            "maxLength": 100,
                            "examples": [
                              "America/Los_Angeles"
                            ]
                          },
                          "revision": {
                            "nullable": true,
                            "type": "string",
                            "pattern": "^\\d+$",
                            "examples": [
                              "1"
                            ]
                          }
                        },
                        "required": [
                          "habitID",
                          "day",
                          "completed",
                          "timeZone",
                          "revision"
                        ],
                        "additionalProperties": false
                      }
                    }
                  },
                  "required": [
                    "asOf",
                    "checkIns"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "default": {
            "description": "The request failed. Read the stable error code before retrying.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        },
                        "requestID": {
                          "type": "string",
                          "format": "uuid",
                          "examples": [
                            "00000000-0000-4000-8000-000000000002"
                          ]
                        },
                        "retryable": {
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "requestID",
                        "retryable"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "habitID",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "examples": [
                "00000000-0000-4000-8000-000000000002"
              ]
            }
          },
          {
            "name": "from",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "examples": [
                "2026-10-20"
              ]
            }
          },
          {
            "name": "through",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "examples": [
                "2026-10-20"
              ]
            }
          }
        ]
      }
    },
    "/api/v1/progress": {
      "get": {
        "operationId": "get_progress",
        "summary": "Get Habit Progress",
        "description": "Read one habit’s current and best streak, with its unit, as of a calendar day. Accounts for schedule changes and breaks. Results reflect server-synced data.",
        "tags": [
          "Habits"
        ],
        "security": [
          {
            "accessKey": []
          }
        ],
        "x-sundial-access": "read",
        "responses": {
          "200": {
            "description": "Confirmed result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "asOf": {
                      "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))$"
                    },
                    "habitID": {
                      "type": "string",
                      "format": "uuid",
                      "examples": [
                        "00000000-0000-4000-8000-000000000002"
                      ]
                    },
                    "day": {
                      "type": "string",
                      "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                    },
                    "current": {
                      "type": "object",
                      "properties": {
                        "count": {
                          "type": "integer",
                          "minimum": 0,
                          "maximum": 9007199254740991
                        },
                        "unit": {
                          "type": "string",
                          "enum": [
                            "days",
                            "times",
                            "weeks"
                          ]
                        }
                      },
                      "required": [
                        "count",
                        "unit"
                      ],
                      "additionalProperties": false
                    },
                    "best": {
                      "type": "object",
                      "properties": {
                        "count": {
                          "type": "integer",
                          "minimum": 0,
                          "maximum": 9007199254740991
                        },
                        "unit": {
                          "type": "string",
                          "enum": [
                            "days",
                            "times",
                            "weeks"
                          ]
                        }
                      },
                      "required": [
                        "count",
                        "unit"
                      ],
                      "additionalProperties": false
                    },
                    "completedDays": {
                      "type": "integer",
                      "minimum": 0,
                      "maximum": 9007199254740991
                    }
                  },
                  "required": [
                    "asOf",
                    "habitID",
                    "day",
                    "current",
                    "best",
                    "completedDays"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "default": {
            "description": "The request failed. Read the stable error code before retrying.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        },
                        "requestID": {
                          "type": "string",
                          "format": "uuid",
                          "examples": [
                            "00000000-0000-4000-8000-000000000002"
                          ]
                        },
                        "retryable": {
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "requestID",
                        "retryable"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "habitID",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "examples": [
                "00000000-0000-4000-8000-000000000002"
              ]
            }
          },
          {
            "name": "day",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "examples": [
                "2026-10-20"
              ],
              "description": "Gregorian calendar date, YYYY-MM-DD, between 1900 and 2100."
            }
          },
          {
            "name": "timeZone",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 100,
              "examples": [
                "America/Los_Angeles"
              ],
              "description": "IANA time zone used to interpret today, such as America/Los_Angeles."
            }
          }
        ]
      }
    },
    "/api/v1/check-ins": {
      "post": {
        "operationId": "set_completion",
        "summary": "Set Habit Completion",
        "description": "Check or uncheck your habit for an explicit date. May publish a shared check-in and trigger friend notifications under your existing sharing settings. Reuse requestID only for identical retries. Read the latest habit and check-in revisions before changing state.",
        "tags": [
          "Habits"
        ],
        "security": [
          {
            "accessKey": []
          }
        ],
        "x-sundial-access": "checkins",
        "responses": {
          "200": {
            "description": "Confirmed result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "requestID": {
                      "type": "string",
                      "format": "uuid",
                      "examples": [
                        "00000000-0000-4000-8000-000000000002"
                      ]
                    },
                    "checkIn": {
                      "type": "object",
                      "properties": {
                        "habitID": {
                          "type": "string",
                          "format": "uuid",
                          "examples": [
                            "00000000-0000-4000-8000-000000000002"
                          ]
                        },
                        "day": {
                          "type": "string",
                          "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                          "examples": [
                            "2026-10-20"
                          ]
                        },
                        "completed": {
                          "type": "boolean"
                        },
                        "timeZone": {
                          "type": "string",
                          "maxLength": 100,
                          "examples": [
                            "America/Los_Angeles"
                          ]
                        },
                        "revision": {
                          "nullable": true,
                          "type": "string",
                          "pattern": "^\\d+$",
                          "examples": [
                            "1"
                          ]
                        }
                      },
                      "required": [
                        "habitID",
                        "day",
                        "completed",
                        "timeZone",
                        "revision"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "requestID",
                    "checkIn"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "default": {
            "description": "The request failed. Read the stable error code before retrying.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        },
                        "requestID": {
                          "type": "string",
                          "format": "uuid",
                          "examples": [
                            "00000000-0000-4000-8000-000000000002"
                          ]
                        },
                        "retryable": {
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "requestID",
                        "retryable"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "requestID": {
                    "type": "string",
                    "format": "uuid",
                    "examples": [
                      "00000000-0000-4000-8000-000000000002"
                    ]
                  },
                  "habitID": {
                    "type": "string",
                    "format": "uuid",
                    "examples": [
                      "00000000-0000-4000-8000-000000000002"
                    ]
                  },
                  "day": {
                    "type": "string",
                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                    "examples": [
                      "2026-10-20"
                    ],
                    "description": "Gregorian calendar date, YYYY-MM-DD, between 1900 and 2100."
                  },
                  "timeZone": {
                    "type": "string",
                    "maxLength": 100,
                    "examples": [
                      "America/Los_Angeles"
                    ],
                    "description": "IANA time zone used to interpret today, such as America/Los_Angeles."
                  },
                  "completed": {
                    "type": "boolean"
                  },
                  "expectedRevision": {
                    "nullable": true,
                    "description": "The check-in revision returned by list_habits; null when no record exists.",
                    "type": "string",
                    "pattern": "^\\d+$",
                    "examples": [
                      "1"
                    ]
                  },
                  "expectedHabitRevision": {
                    "type": "string",
                    "pattern": "^\\d+$",
                    "examples": [
                      "1"
                    ],
                    "description": "The habit revision returned by list_habits. Changes to the habit or its sharing invalidate it."
                  }
                },
                "required": [
                  "requestID",
                  "habitID",
                  "day",
                  "timeZone",
                  "completed",
                  "expectedRevision",
                  "expectedHabitRevision"
                ],
                "additionalProperties": false
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "accessKey": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "Sundial access key"
      }
    }
  }
}
