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 · uuidUnique identifier for the milestone.
-
namestring -
descriptionstring · nullable -
duestring · date · nullableThe day the milestone should be reached.
-
visibilitystring · nullableWho can see the milestone. New milestones are
private.privatepublicshared -
collaborator_user_idsarray of strings · uuid · nullableThe users a
sharedmilestone is shared with. The list has no effect under any other visibility. -
archivedboolean · nullableWhether the milestone has been archived. Archived milestones are still returned by List milestones.
-
pinnedboolean · nullableWhether your key’s user has pinned this milestone.
-
task_countinteger · nullableTasks in the milestone, open and completed.
-
completed_task_countinteger · nullable -
task_progressnumber · nullablecompleted_task_countdivided bytask_count, rounded to two places. Null when the milestone has no tasks. -
tasksarray of tasks · nullableEvery task in the milestone, open and completed.
{
"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",
…
},
…
]
}
#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
-
collectionobjectShow 2 child attributesHide child attributes
-
recordsarray of milestones -
total_resultsintegerThe number of milestones returned.
-
curl https://api.carom.io/milestones \
-H "Authorization: Bearer $CAROM_API_KEY"
{
"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,
…
}
]
}
}
#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-KeystringA 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
-
milestoneobjectrequiredShow 6 child attributesHide child attributes
-
namestringrequired -
descriptionstring -
duestring · dateAs
YYYY-MM-DD. -
visibilitystringdefaultprivateprivatepublicshared -
collaborator_user_idsarray of strings · uuidUsers to share the milestone with. They can see it only while
visibilityisshared. -
archivedbooleandefaultfalse
-
Returns
The new milestone object, wrapped in milestone, with status 201.
Errors
- 400
invalid_requestA field failed validation, for example a missingnameor an unknownvisibility, or theIdempotency-Keyheader is malformed.error.fieldssays which. - 409
idempotency_key_in_useA request with the sameIdempotency-Keyis still in progress. Retry shortly.
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"
}
}'
{
"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": []
}
}
#Retrieve a milestone
Returns a single milestone with its tasks and progress.
Path parameters
-
idstring · uuidrequiredThe milestone’s id.
Returns
The milestone object, wrapped in milestone.
Errors
- 404
record_not_foundNo milestone with that id is visible to your key.
curl https://api.carom.io/milestones/f3bb9a33-6078-4fbc-9166-a28e5cc0dce7 \
-H "Authorization: Bearer $CAROM_API_KEY"
{
"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,
…
}
}
#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
-
milestoneobjectrequiredAny of the attributes accepted by Create a milestone, plus one more.
Show 1 child attributeHide child attributes
-
pinnedbooleantruepins the milestone for your key’s user;falseunpins it. Pins are per user. See Pins.
-
Returns
The updated milestone object, wrapped in milestone.
Errors
- 400
invalid_requestA field failed validation, for example an emptynameor an unknownvisibility.error.fieldssays which. - 404
record_not_foundNo milestone with that id is visible to your key.
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"
]
}
}'
{
"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 a milestone
Path parameters
-
idstring · uuidrequired
Returns
An empty response with status 204.
Errors
- 404
record_not_foundNo milestone with that id is visible to your key.
curl -X DELETE https://api.carom.io/milestones/36392018-f10c-416c-b4a2-768a23d7b2c6 \
-H "Authorization: Bearer $CAROM_API_KEY"
No content