Milestones

A milestone is a named goal with an optional due date, such as “Wildgrove renewal signed by September 30.” Tasks belong to a milestone through their milestone_id, and the milestone reports how many of them are done. Use this resource to set up milestones and track progress toward them.

Each milestone has a visibility that decides who can see it, and so whether it is visible to your key: private milestones are visible only to the user who created them, public milestones to everyone in the account, and shared milestones to the creator and the users listed in collaborator_user_ids. Anyone who can see a milestone can edit and delete it.

#The milestone object

Returned by every milestone endpoint, always with its tasks. The tasks and both task counts include only tasks visible to your key.

Attributes

  • idstring · uuid

    Unique identifier for the milestone.

  • namestring
  • descriptionstring · nullable
  • duestring · date · nullable

    The day the milestone should be reached.

  • visibilitystring · nullable

    Who can see the milestone. New milestones are private.

    privatepublicshared
  • collaborator_user_idsarray of strings · uuid · nullable

    The users a shared milestone is shared with. The list has no effect under any other visibility.

  • archivedboolean · nullable

    Whether the milestone has been archived. Archived milestones are still returned by List milestones.

  • pinnedboolean · nullable

    Whether your key’s user has pinned this milestone.

  • task_countinteger · nullable

    Tasks in the milestone, open and completed.

  • completed_task_countinteger · nullable
  • task_progressnumber · nullable

    completed_task_count divided by task_count, rounded to two places. Null when the milestone has no tasks.

  • tasksarray of tasks · nullable

    Every task in the milestone, open and completed.

The milestone object
{
  "id": "f3bb9a33-6078-4fbc-9166-a28e5cc0dce7",
  "name": "Wildgrove renewal",
  "description": "Signed 2027 contract by the end of September.",
  "due": "2026-09-30",
  "visibility": "shared",
  "collaborator_user_ids": ["44c3f6da-393b-4664-9bfa-3c14e76b8cb8"],
  "archived": false,
  "pinned": true,
  "task_count": 3,
  "completed_task_count": 1,
  "task_progress": 0.33,
  "tasks": [
    {
      "id": "e7f8a9b0-c1d2-4e3f-8a4b-5c6d7e8f9a01",
      "assignment": "Send the Q4 renewal proposal",
      "due": "2026-09-12",
      "completed_at": "2026-09-11T16:20:00.000Z",
      "milestone_id": "f3bb9a33-6078-4fbc-9166-a28e5cc0dce7",
      …
    },
    {
      "id": "0361c1d0-a72d-43bc-86c1-26537f0236ec",
      "assignment": "Confirm headcount for the 2027 contract",
      "due": "2026-09-18",
      "completed_at": null,
      "milestone_id": "f3bb9a33-6078-4fbc-9166-a28e5cc0dce7",
      …
    },
    …
  ]
}
get/milestones Read key

#List milestones

Returns every milestone visible to your key in one response, including archived ones, each with its tasks; the list isn’t paginated. It takes no parameters.

Returns

  • collectionobject
    Show 2 child attributesHide child attributes
    • recordsarray of milestones
    • total_resultsinteger

      The number of milestones returned.

get/milestones
curl https://api.carom.io/milestones \
  -H "Authorization: Bearer $CAROM_API_KEY"
Response200
{
  "collection": {
    "total_results": 2,
    "records": [
      {
        "id": "f3bb9a33-6078-4fbc-9166-a28e5cc0dce7",
        "name": "Wildgrove renewal",
        "due": "2026-09-30",
        "task_progress": 0.33,
        …
      },
      {
        "id": "36392018-f10c-416c-b4a2-768a23d7b2c6",
        "name": "Harbor Lane onboarding",
        "due": "2026-10-15",
        "task_progress": null,
        …
      }
    ]
  }
}
post/milestones Write key

#Create a milestone

Creates a milestone owned by your key’s user. It starts with no tasks; add tasks by setting their milestone_id with Create a task or Update a task.

Headers

  • Idempotency-Keystring

    A key you choose, 1 to 255 printable ASCII characters, that makes the request safe to retry. When your key’s user repeats a request to this endpoint with the same key within 24 hours of a successful one, Carom returns the first response again instead of creating a second milestone. The request body isn’t compared, so use a new key for each new milestone. A failed request doesn’t use up its key.

Request body application/json

  • milestoneobjectrequired
    Show 6 child attributesHide child attributes
    • namestringrequired
    • descriptionstring
    • duestring · date

      As YYYY-MM-DD.

    • visibilitystringdefault private
      privatepublicshared
    • collaborator_user_idsarray of strings · uuid

      Users to share the milestone with. They can see it only while visibility is shared.

    • archivedbooleandefault false

Returns

The new milestone object, wrapped in milestone, with status 201.

Errors

  • 400invalid_requestA field failed validation, for example a missing name or an unknown visibility, or the Idempotency-Key header is malformed. error.fields says which.
  • 409idempotency_key_in_useA request with the same Idempotency-Key is still in progress. Retry shortly.
post/milestones
curl https://api.carom.io/milestones \
  -H "Authorization: Bearer $CAROM_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 5f0c2a9e-8d41-4b7a-9e63-1c2d7f4a8b90" \
  -d '{
    "milestone": {
      "name": "Harbor Lane onboarding",
      "due": "2026-10-15",
      "visibility": "public"
    }
  }'
Response201
{
  "milestone": {
    "id": "36392018-f10c-416c-b4a2-768a23d7b2c6",
    "name": "Harbor Lane onboarding",
    "description": null,
    "due": "2026-10-15",
    "visibility": "public",
    "collaborator_user_ids": [],
    "archived": false,
    "pinned": false,
    "task_count": 0,
    "completed_task_count": 0,
    "task_progress": null,
    "tasks": []
  }
}
get/milestones/{id} Read key

#Retrieve a milestone

Returns a single milestone with its tasks and progress.

Path parameters

  • idstring · uuidrequired

    The milestone’s id.

Returns

The milestone object, wrapped in milestone.

Errors

  • 404record_not_foundNo milestone with that id is visible to your key.
get/milestones/{id}
curl https://api.carom.io/milestones/f3bb9a33-6078-4fbc-9166-a28e5cc0dce7 \
  -H "Authorization: Bearer $CAROM_API_KEY"
Response200
{
  "milestone": {
    "id": "f3bb9a33-6078-4fbc-9166-a28e5cc0dce7",
    "name": "Wildgrove renewal",
    "due": "2026-09-30",
    "task_count": 3,
    "completed_task_count": 1,
    "task_progress": 0.33,
    …
  }
}
patch/milestones/{id} Write key

#Update a milestone

Changes the fields you send and leaves the rest alone. collaborator_user_ids, when sent, replaces the current list.

Path parameters

  • idstring · uuidrequired

Request body application/json

  • milestoneobjectrequired

    Any of the attributes accepted by Create a milestone, plus one more.

    Show 1 child attributeHide child attributes
    • pinnedboolean

      true pins the milestone for your key’s user; false unpins it. Pins are per user. See Pins.

Returns

The updated milestone object, wrapped in milestone.

Errors

  • 400invalid_requestA field failed validation, for example an empty name or an unknown visibility. error.fields says which.
  • 404record_not_foundNo milestone with that id is visible to your key.
patch/milestones/{id}
curl -X PATCH https://api.carom.io/milestones/f3bb9a33-6078-4fbc-9166-a28e5cc0dce7 \
  -H "Authorization: Bearer $CAROM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "milestone": {
      "due": "2026-10-09",
      "visibility": "shared",
      "collaborator_user_ids": [
        "44c3f6da-393b-4664-9bfa-3c14e76b8cb8",
        "ea5f6800-b2b7-4df4-a5e9-3a4ed2d84961"
      ]
    }
  }'
Response200
{
  "milestone": {
    "id": "f3bb9a33-6078-4fbc-9166-a28e5cc0dce7",
    "name": "Wildgrove renewal",
    "due": "2026-10-09",
    "visibility": "shared",
    "collaborator_user_ids": [
      "44c3f6da-393b-4664-9bfa-3c14e76b8cb8",
      "ea5f6800-b2b7-4df4-a5e9-3a4ed2d84961"
    ],
    …
  }
}
delete/milestones/{id} Write key

#Delete a milestone

Permanently deletes a milestone and every user’s pin on it. Its tasks are kept, including ones not visible to your key; their milestone_id becomes null. Anyone who can see a milestone can delete it.

Path parameters

  • idstring · uuidrequired

Returns

An empty response with status 204.

Errors

  • 404record_not_foundNo milestone with that id is visible to your key.
delete/milestones/{id}
curl -X DELETE https://api.carom.io/milestones/36392018-f10c-416c-b4a2-768a23d7b2c6 \
  -H "Authorization: Bearer $CAROM_API_KEY"
Response204
No content