---
title: "PATCH /api/v1/habits/{habitId}"
method: PATCH
path: "/api/v1/habits/{habitId}"
tags: ["PublicHabits"]
---

# PATCH /api/v1/habits/{habitId}

`PATCH /api/v1/habits/{habitId}`

## Request

- Base URL: `https://api.habitpocket.io` (the document declares no server; this is the origin it was published from)
- URL: `https://api.habitpocket.io/api/v1/habits/{habitId}`
- Auth: API key in header `X-API-KEY`

## Path parameters

- `habitId` string, uuid, required

## Request body

- UpdatePublicHabitRequest
  - `name` string, nullable: New name. Can't be blank or null.
  - `description` string, nullable: New description, or null to remove it.
  - `color` string, nullable: New hex color, e.g. "#16a34a". Can't be null — a habit always has a color.
  - `unit` string, nullable: metric habits only: unit label, e.g. "km". Null removes it.
  - `target` number, double, nullable: metric habits only: daily goal. Null removes it.
  - `timeTarget` string, nullable: time habits only: ideal time of day, "HH:mm". Null removes it.
  - `goalOperator` string, nullable: metric/time habits only: "above" (at least), "exact", or "below" (at most). Null resets to the default.
  - `excludedDays` integer[], nullable: Days of week the habit doesn't apply (0=Sun … 6=Sat). Empty or null means every day.
  - `conditionalStylingEnabled` boolean, nullable: metric/time habits only: turn conditional styling on or off. Can't be null. Turning it on needs at least one band.
  - `conditionalStylingBands` PublicColorBand[], nullable: metric/time habits only: color bands, lowest (or earliest) first; time bands may run past midnight. A day takes the color of the first band whose upTo is above its value. upTo is a number string for metric habits ("5000") or "HH:mm" for time habits, and the last band's upTo is null. Replaces the whole list; null or [] removes every band.
    - `color` string, nullable
    - `upTo` string, nullable
  - `avoidSince` string, nullable: boolean/metric habits only: "YYYY-MM-DD" makes this an avoid habit — days with nothing logged from that date on count as clean days, and a done entry (or a metric value above the target, 0 when there is none) is a slip. On a metric habit the target becomes a daily limit and goalOperator becomes "below". Null makes it a normal habit again.
  - `sectionId` string, uuid, nullable: Moves the habit into that section. Must be one of yours; can't be null.

## Response `200`

OK

- PublicHabitModel
  - `id` string, uuid
  - `name` string, nullable
  - `description` string, nullable
  - `type` string, nullable
  - `color` string, nullable
  - `unit` string, nullable
  - `target` number, double, nullable
  - `timeTarget` string, nullable
  - `goalOperator` string, nullable
  - `isMultiSelect` boolean
  - `options` PublicSelectOptionModel[], nullable
    - `id` string, uuid
    - `label` string, nullable
    - `color` string, nullable
  - `excludedDays` integer[], nullable
  - `conditionalStylingEnabled` boolean
  - `conditionalStylingBands` PublicColorBand[], nullable
    - `color` string, nullable
    - `upTo` string, nullable
  - `avoidSince` string, date, nullable
  - `currentStreak` integer
  - `bestStreak` integer
  - `section` PublicSectionModel
    - `id` string, uuid
    - `name` string, nullable
  - `createdAt` string, date-time

## Other responses

- `400`: Bad Request
- `401`: Unauthorized
- `402`: Payment Required
- `404`: Not Found

---

[API](https://skmtc.dev/habitpocket/apis/metricspocket-public-api.md) - [All operations](https://skmtc.dev/habitpocket/apis/metricspocket-public-api/llms.txt) - [OpenAPI document](https://skmtc.dev/habitpocket/apis/metricspocket-public-api/revisions/28a2063c7bbe?raw)
