Workouts reference
List, read, log, replace and delete finished workouts with their exercises and sets.
The DailyGoal API is not available on the Free plan. It works with a paid plan or during a free trial. See plans.
Usage notes
These operations read and write finished workouts. get_workout returns completed sets, with isTruncated when an older workout exceeds the response bounds. A truncated workout cannot be replaced; edit it in the app or delete it.
All operations require Pro or a trial. GET and DELETE take query parameters; other methods take a JSON body. The input table also includes any MCP-only idempotency_key argument; REST sends it as a header. See retrying creates. Example ids are synthetic; find your own with the search and list operations.
Operations
list_workouts: List workoutsget_workout: Get workoutlog_workout: Log workoutreplace_workout: Replace workoutdelete_workout: Delete workout
list_workouts
GET https://api.dailygoal.fit/v1/workouts
MCP tool list_workouts · Read-only · DailyGoal data only
List finished workouts as summaries, newest first, with pagination. Omit from and to to list every workout, or give either to bound the date window. Summaries have no sets; use get_workout for one workout's exercises and sets.
Input
| Field | Type | Description |
|---|---|---|
| fromoptional | string (YYYY-MM-DD) | First Activity Day to include, YYYY-MM-DD. Omit for no lower bound. |
| tooptional | string (YYYY-MM-DD) | Last Activity Day to include, YYYY-MM-DD, inclusive. Omit for no upper bound. |
| limitoptional | integer | Page size. Defaults to 50. |
| cursoroptional | string | nextCursor from the previous page, with the same from and to. |
Full input schema, including bounds and nested alternatives (MCP)
{
"type": "object",
"properties": {
"from": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}$",
"description": "First Activity Day to include, YYYY-MM-DD. Omit for no lower bound."
},
"to": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}$",
"description": "Last Activity Day to include, YYYY-MM-DD, inclusive. Omit for no upper bound."
},
"limit": {
"type": "integer",
"minimum": 1,
"maximum": 100,
"description": "Page size. Defaults to 50."
},
"cursor": {
"type": "string",
"description": "nextCursor from the previous page, with the same from and to."
}
},
"additionalProperties": true
}Output
| Field | Type | Description |
|---|---|---|
| workouts | object[] | |
| workouts[].id | string | Workout id for get_workout, replace_workout and delete_workout. |
| workouts[].name | string | |
| workouts[].date | string (YYYY-MM-DD) | Activity Day the workout counts toward, YYYY-MM-DD. |
| workouts[].startTimeoptional | string | ISO 8601 timestamp. |
| workouts[].endTimeoptional | string | ISO 8601 timestamp. |
| workouts[].durationSecondsoptional | integer | |
| workouts[].notesoptional | string | |
| workouts[].estimatedCaloriesoptional | number | Estimated kcal burned. Absent when the user has no known body weight. |
| workouts[].exerciseCount | integer | |
| workouts[].isTruncatedoptional | true | Present and true when the workout holds more than 30 exercises, so exerciseCount counts only 30 of them. |
| hasMore | boolean | True when more workouts match. Pass nextCursor to get them. |
| nextCursor | string | null |
Full output schema
{
"type": "object",
"properties": {
"workouts": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "Workout id for get_workout, replace_workout and delete_workout."
},
"name": {
"type": "string"
},
"date": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}$",
"description": "Activity Day the workout counts toward, YYYY-MM-DD."
},
"startTime": {
"type": "string",
"description": "ISO 8601 timestamp."
},
"endTime": {
"type": "string",
"description": "ISO 8601 timestamp."
},
"durationSeconds": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"notes": {
"type": "string"
},
"estimatedCalories": {
"type": "number",
"minimum": 0,
"description": "Estimated kcal burned. Absent when the user has no known body weight."
},
"exerciseCount": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"isTruncated": {
"type": "boolean",
"enum": [
true
],
"description": "Present and true when the workout holds more than 30 exercises, so exerciseCount counts only 30 of them."
}
},
"required": [
"id",
"name",
"date",
"exerciseCount"
],
"additionalProperties": true
}
},
"hasMore": {
"type": "boolean",
"description": "True when more workouts match. Pass nextCursor to get them."
},
"nextCursor": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
}
},
"required": [
"workouts",
"hasMore",
"nextCursor"
],
"additionalProperties": true
}Example request
curl "https://api.dailygoal.fit/v1/workouts?from=2026-09-08&to=2026-09-14&limit=20" \
-H "Authorization: Bearer $DAILYGOAL_API_TOKEN"{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "list_workouts",
"arguments": {
"from": "2026-09-08",
"to": "2026-09-14",
"limit": 20
}
}
}Example response
Synthetic data. REST returns this object as the body; MCP returns it as structuredContent.
{
"workouts": [
{
"id": "m1774k2j9h6g3f0d7s4a1p8o5i2u9y6t",
"name": "Push day",
"date": "2026-09-14",
"startTime": "2026-09-14T17:30:00.000Z",
"endTime": "2026-09-14T18:25:00.000Z",
"durationSeconds": 3300,
"notes": "Bench felt strong.",
"estimatedCalories": 216,
"exerciseCount": 2
},
{
"id": "m1775l3k0j7h4g1f8d5s2a9p6o3i0u7y",
"name": "Easy run",
"date": "2026-09-12",
"startTime": "2026-09-12T08:05:00.000Z",
"endTime": "2026-09-12T08:41:00.000Z",
"durationSeconds": 2160,
"estimatedCalories": 420,
"exerciseCount": 1
}
],
"hasMore": false,
"nextCursor": null
}Errors
unauthorized(401)origin_not_allowed(403)misdirected_request(421)subscription_required(403)rate_limited(429)validation_failed(400)internal_error(500)
get_workout
GET https://api.dailygoal.fit/v1/workouts/detail
MCP tool get_workout · Read-only · DailyGoal data only
Get one finished workout's exercises and completed sets. Oversized workouts return a preview with isTruncated true. Use list_workouts to browse workouts by date.
Input
| Field | Type | Description |
|---|---|---|
| id | string | Workout id from list_workouts or log_workout. |
Full input schema, including bounds and nested alternatives (MCP)
{
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "Workout id from list_workouts or log_workout."
}
},
"required": [
"id"
],
"additionalProperties": true
}Output
| Field | Type | Description |
|---|---|---|
| id | string | Workout id for get_workout, replace_workout and delete_workout. |
| name | string | |
| date | string (YYYY-MM-DD) | Activity Day the workout counts toward, YYYY-MM-DD. |
| startTimeoptional | string | ISO 8601 timestamp. |
| endTimeoptional | string | ISO 8601 timestamp. |
| durationSecondsoptional | integer | |
| notesoptional | string | |
| estimatedCaloriesoptional | number | Estimated kcal burned. Absent when the user has no known body weight. |
| exercises | object[] | |
| exercises[].exerciseId | string | |
| exercises[].name | string | |
| exercises[].sets | object[] | |
| exercises[].sets[].setNumber | integer | |
| exercises[].sets[].setType | "warmup" | "working" | |
| exercises[].sets[].weightoptional | object | Load in the user's preferred strength unit. |
| exercises[].sets[].weight.value | number | |
| exercises[].sets[].weight.unit | "kg" | "lb" | |
| exercises[].sets[].weightKgoptional | number | Canonical load in kilograms. |
| exercises[].sets[].repsoptional | integer | |
| exercises[].sets[].durationSecondsoptional | number | |
| exercises[].sets[].distanceMetersoptional | number | |
| exercises[].sets[].holdSecondsoptional | number | |
| exercises[].sets[].intensityoptional | number | Effort from 0 to 10. |
| isTruncatedoptional | true | Present and true when the workout holds more than 30 exercises, or more than 30 sets in one exercise, so this result leaves some out. A replace_workout built from this result drops them. |
Full output schema
{
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "Workout id for get_workout, replace_workout and delete_workout."
},
"name": {
"type": "string"
},
"date": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}$",
"description": "Activity Day the workout counts toward, YYYY-MM-DD."
},
"startTime": {
"type": "string",
"description": "ISO 8601 timestamp."
},
"endTime": {
"type": "string",
"description": "ISO 8601 timestamp."
},
"durationSeconds": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"notes": {
"type": "string"
},
"estimatedCalories": {
"type": "number",
"minimum": 0,
"description": "Estimated kcal burned. Absent when the user has no known body weight."
},
"exercises": {
"type": "array",
"items": {
"type": "object",
"properties": {
"exerciseId": {
"type": "string"
},
"name": {
"type": "string"
},
"sets": {
"type": "array",
"items": {
"type": "object",
"properties": {
"setNumber": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"setType": {
"type": "string",
"enum": [
"warmup",
"working"
]
},
"weight": {
"type": "object",
"properties": {
"value": {
"type": "number",
"minimum": 0
},
"unit": {
"type": "string",
"enum": [
"kg",
"lb"
]
}
},
"required": [
"value",
"unit"
],
"additionalProperties": true,
"description": "Load in the user's preferred strength unit."
},
"weightKg": {
"type": "number",
"minimum": 0,
"description": "Canonical load in kilograms."
},
"reps": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"durationSeconds": {
"type": "number",
"minimum": 0
},
"distanceMeters": {
"type": "number",
"minimum": 0
},
"holdSeconds": {
"type": "number",
"minimum": 0
},
"intensity": {
"type": "number",
"description": "Effort from 0 to 10."
}
},
"required": [
"setNumber",
"setType"
],
"additionalProperties": true
}
}
},
"required": [
"exerciseId",
"name",
"sets"
],
"additionalProperties": true
}
},
"isTruncated": {
"type": "boolean",
"enum": [
true
],
"description": "Present and true when the workout holds more than 30 exercises, or more than 30 sets in one exercise, so this result leaves some out. A replace_workout built from this result drops them."
}
},
"required": [
"id",
"name",
"date",
"exercises"
],
"additionalProperties": true
}Example request
curl "https://api.dailygoal.fit/v1/workouts/detail?id=m1774k2j9h6g3f0d7s4a1p8o5i2u9y6t" \
-H "Authorization: Bearer $DAILYGOAL_API_TOKEN"{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "get_workout",
"arguments": {
"id": "m1774k2j9h6g3f0d7s4a1p8o5i2u9y6t"
}
}
}Example response
Synthetic data. REST returns this object as the body; MCP returns it as structuredContent.
{
"id": "m1774k2j9h6g3f0d7s4a1p8o5i2u9y6t",
"name": "Push day",
"date": "2026-09-14",
"startTime": "2026-09-14T17:30:00.000Z",
"endTime": "2026-09-14T18:25:00.000Z",
"durationSeconds": 3300,
"notes": "Bench felt strong.",
"estimatedCalories": 216,
"exercises": [
{
"exerciseId": "jx71q4w7e0r3t6y9u2i5o8p1a4s7d0f3",
"name": "Barbell Bench Press",
"sets": [
{
"setNumber": 1,
"setType": "warmup",
"weight": {
"value": 40,
"unit": "kg"
},
"weightKg": 40,
"reps": 10
},
{
"setNumber": 2,
"setType": "working",
"weight": {
"value": 70,
"unit": "kg"
},
"weightKg": 70,
"reps": 8,
"intensity": 7
},
{
"setNumber": 3,
"setType": "working",
"weight": {
"value": 70,
"unit": "kg"
},
"weightKg": 70,
"reps": 8,
"intensity": 8
}
]
},
{
"exerciseId": "jx73e6r9t2y5u8i1o4p7a0s3d6f9g2h5",
"name": "Overhead Press",
"sets": [
{
"setNumber": 1,
"setType": "working",
"weight": {
"value": 40,
"unit": "kg"
},
"weightKg": 40,
"reps": 8,
"intensity": 7
},
{
"setNumber": 2,
"setType": "working",
"weight": {
"value": 40,
"unit": "kg"
},
"weightKg": 40,
"reps": 7,
"intensity": 9
}
]
}
]
}Errors
unauthorized(401)origin_not_allowed(403)misdirected_request(421)subscription_required(403)rate_limited(429)validation_failed(400)not_found(404)internal_error(500)
log_workout
POST https://api.dailygoal.fit/v1/workouts
MCP tool log_workout · Changes data · DailyGoal data only · Accepts Idempotency-Key
Log a workout that is already finished, with its exercises and sets. Get exercise ids from search_exercises. Each call adds a new workout; to correct an existing one use replace_workout.
Input
| Field | Type | Description |
|---|---|---|
| name | string | |
| durationSecondsoptional | integer | Length of the whole session in seconds. Optional. Record a run's or set's own time on the set's durationSeconds. |
| notesoptional | string | |
| exercises | object[] | |
| exercises[].exerciseIdoptional | string | Exercise id from search_exercises. Preferred. |
| exercises[].nameoptional | string | Exact catalogue name, used when exerciseId is absent. |
| exercises[].sets | object[] | |
| exercises[].sets[].setTypeoptional | "warmup" | "working" | Defaults to working. |
| exercises[].sets[].weightoptional | object | A load with its unit. Stored as kilograms. |
| exercises[].sets[].weight.value | number | |
| exercises[].sets[].weight.unit | "kg" | "lb" | |
| exercises[].sets[].loadIntentoptional | "bar_total" | "per_hand" | "plates_each_side" | "assistance" | "added_bodyweight" | "machine_stack" | "custom" | What the weight means, for example per_hand for dumbbells. Omit for a plain total load. |
| exercises[].sets[].repsoptional | integer | |
| exercises[].sets[].durationSecondsoptional | number | Time this set took, in seconds. For a timed effort such as 5 km in 28 minutes, put 1680 here with distanceMeters 5000. |
| exercises[].sets[].distanceMetersoptional | number | |
| exercises[].sets[].holdSecondsoptional | number | |
| exercises[].sets[].intensityoptional | number | Effort from 0 to 10. |
| dateoptional | string (YYYY-MM-DD) | Activity Day, YYYY-MM-DD. Defaults to today in the user's timezone. |
| idempotency_keyoptional | string | Optional. A unique value for this create, for example a UUID. Retrying with the same key and arguments within 24 hours returns the first result instead of creating a duplicate. |
Full input schema, including bounds and nested alternatives (MCP)
{
"type": "object",
"properties": {
"name": {
"type": "string",
"pattern": "\\S",
"maxLength": 120
},
"durationSeconds": {
"type": "integer",
"minimum": 60,
"maximum": 43200,
"description": "Length of the whole session in seconds. Optional. Record a run's or set's own time on the set's durationSeconds."
},
"notes": {
"type": "string",
"maxLength": 2000
},
"exercises": {
"type": "array",
"items": {
"type": "object",
"properties": {
"exerciseId": {
"type": "string",
"description": "Exercise id from search_exercises. Preferred."
},
"name": {
"type": "string",
"pattern": "\\S",
"description": "Exact catalogue name, used when exerciseId is absent."
},
"sets": {
"type": "array",
"items": {
"type": "object",
"properties": {
"setType": {
"type": "string",
"enum": [
"warmup",
"working"
],
"description": "Defaults to working."
},
"weight": {
"type": "object",
"properties": {
"value": {
"type": "number",
"minimum": 0
},
"unit": {
"type": "string",
"enum": [
"kg",
"lb"
]
}
},
"required": [
"value",
"unit"
],
"additionalProperties": true,
"description": "A load with its unit. Stored as kilograms."
},
"loadIntent": {
"type": "string",
"enum": [
"bar_total",
"per_hand",
"plates_each_side",
"assistance",
"added_bodyweight",
"machine_stack",
"custom"
],
"description": "What the weight means, for example per_hand for dumbbells. Omit for a plain total load."
},
"reps": {
"type": "integer",
"minimum": 0,
"maximum": 1000
},
"durationSeconds": {
"type": "number",
"minimum": 0,
"maximum": 21600,
"description": "Time this set took, in seconds. For a timed effort such as 5 km in 28 minutes, put 1680 here with distanceMeters 5000."
},
"distanceMeters": {
"type": "number",
"minimum": 0,
"maximum": 500000
},
"holdSeconds": {
"type": "number",
"minimum": 0,
"maximum": 3600
},
"intensity": {
"type": "number",
"minimum": 0,
"maximum": 10,
"description": "Effort from 0 to 10."
}
},
"additionalProperties": true
},
"minItems": 1,
"maxItems": 30
}
},
"required": [
"sets"
],
"additionalProperties": true,
"description": "One exercise with its sets. Give exerciseId or name; an unknown exercise fails with suggestions."
},
"minItems": 1,
"maxItems": 30
},
"date": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}$",
"description": "Activity Day, YYYY-MM-DD. Defaults to today in the user's timezone."
},
"idempotency_key": {
"type": "string",
"maxLength": 255,
"description": "Optional. A unique value for this create, for example a UUID. Retrying with the same key and arguments within 24 hours returns the first result instead of creating a duplicate."
}
},
"required": [
"name",
"exercises"
],
"additionalProperties": true
}Output
| Field | Type | Description |
|---|---|---|
| id | string | |
| date | string (YYYY-MM-DD) | The Activity Day the workout was saved to. |
| timezone | string | IANA timezone that defines that Activity Day. |
| estimatedCaloriesoptional | number |
Full output schema
{
"type": "object",
"properties": {
"id": {
"type": "string"
},
"date": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}$",
"description": "The Activity Day the workout was saved to."
},
"timezone": {
"type": "string",
"description": "IANA timezone that defines that Activity Day."
},
"estimatedCalories": {
"type": "number",
"minimum": 0
}
},
"required": [
"id",
"date",
"timezone"
],
"additionalProperties": true
}Example request
The REST example uses OpenSSL to generate a fresh key for a new create. To retry that create, rerun only the curl command with the same key and input. You may send that key as idempotency_key in the MCP arguments too.
DAILYGOAL_IDEMPOTENCY_KEY="$(openssl rand -hex 16)"
curl -X POST "https://api.dailygoal.fit/v1/workouts" \
-H "Authorization: Bearer $DAILYGOAL_API_TOKEN" \
-H "Idempotency-Key: $DAILYGOAL_IDEMPOTENCY_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"Push day","date":"2026-09-14","durationSeconds":3300,"notes":"Bench felt strong.","exercises":[{"exerciseId":"jx71q4w7e0r3t6y9u2i5o8p1a4s7d0f3","sets":[{"setType":"warmup","weight":{"value":40,"unit":"kg"},"reps":10},{"weight":{"value":70,"unit":"kg"},"reps":8,"intensity":7},{"weight":{"value":70,"unit":"kg"},"reps":8,"intensity":8}]},{"exerciseId":"jx73e6r9t2y5u8i1o4p7a0s3d6f9g2h5","sets":[{"weight":{"value":40,"unit":"kg"},"reps":8,"intensity":7},{"weight":{"value":40,"unit":"kg"},"reps":7,"intensity":9}]}]}'{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "log_workout",
"arguments": {
"name": "Push day",
"date": "2026-09-14",
"durationSeconds": 3300,
"notes": "Bench felt strong.",
"exercises": [
{
"exerciseId": "jx71q4w7e0r3t6y9u2i5o8p1a4s7d0f3",
"sets": [
{
"setType": "warmup",
"weight": {
"value": 40,
"unit": "kg"
},
"reps": 10
},
{
"weight": {
"value": 70,
"unit": "kg"
},
"reps": 8,
"intensity": 7
},
{
"weight": {
"value": 70,
"unit": "kg"
},
"reps": 8,
"intensity": 8
}
]
},
{
"exerciseId": "jx73e6r9t2y5u8i1o4p7a0s3d6f9g2h5",
"sets": [
{
"weight": {
"value": 40,
"unit": "kg"
},
"reps": 8,
"intensity": 7
},
{
"weight": {
"value": 40,
"unit": "kg"
},
"reps": 7,
"intensity": 9
}
]
}
]
}
}
}Example response
Synthetic data. REST returns this object as the body; MCP returns it as structuredContent.
{
"id": "m1774k2j9h6g3f0d7s4a1p8o5i2u9y6t",
"date": "2026-09-14",
"timezone": "Europe/London",
"estimatedCalories": 216
}Errors
unauthorized(401)origin_not_allowed(403)misdirected_request(421)subscription_required(403)rate_limited(429)validation_failed(400)idempotency_conflict(409)internal_error(500)
replace_workout
PUT https://api.dailygoal.fit/v1/workouts
MCP tool replace_workout · Changes data · Destructive · DailyGoal data only
Replace a finished workout's name, date, duration, notes and its whole list of exercises and sets in one call. Exercises and sets you leave out are removed, and omitted notes are cleared. To add a new workout use log_workout.
Input
| Field | Type | Description |
|---|---|---|
| id | string | Workout id to replace. |
| name | string | |
| durationSecondsoptional | integer | Length of the whole session in seconds. Optional. Record a run's or set's own time on the set's durationSeconds. |
| notesoptional | string | |
| exercises | object[] | |
| exercises[].exerciseIdoptional | string | Exercise id from search_exercises. Preferred. |
| exercises[].nameoptional | string | Exact catalogue name, used when exerciseId is absent. |
| exercises[].sets | object[] | |
| exercises[].sets[].setTypeoptional | "warmup" | "working" | Defaults to working. |
| exercises[].sets[].weightoptional | object | A load with its unit. Stored as kilograms. |
| exercises[].sets[].weight.value | number | |
| exercises[].sets[].weight.unit | "kg" | "lb" | |
| exercises[].sets[].loadIntentoptional | "bar_total" | "per_hand" | "plates_each_side" | "assistance" | "added_bodyweight" | "machine_stack" | "custom" | What the weight means, for example per_hand for dumbbells. Omit for a plain total load. |
| exercises[].sets[].repsoptional | integer | |
| exercises[].sets[].durationSecondsoptional | number | Time this set took, in seconds. For a timed effort such as 5 km in 28 minutes, put 1680 here with distanceMeters 5000. |
| exercises[].sets[].distanceMetersoptional | number | |
| exercises[].sets[].holdSecondsoptional | number | |
| exercises[].sets[].intensityoptional | number | Effort from 0 to 10. |
| dateoptional | string (YYYY-MM-DD) | Activity Day, YYYY-MM-DD. Defaults to the workout's current date. |
Full input schema, including bounds and nested alternatives (MCP)
{
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "Workout id to replace."
},
"name": {
"type": "string",
"pattern": "\\S",
"maxLength": 120
},
"durationSeconds": {
"type": "integer",
"minimum": 60,
"maximum": 43200,
"description": "Length of the whole session in seconds. Optional. Record a run's or set's own time on the set's durationSeconds."
},
"notes": {
"type": "string",
"maxLength": 2000
},
"exercises": {
"type": "array",
"items": {
"type": "object",
"properties": {
"exerciseId": {
"type": "string",
"description": "Exercise id from search_exercises. Preferred."
},
"name": {
"type": "string",
"pattern": "\\S",
"description": "Exact catalogue name, used when exerciseId is absent."
},
"sets": {
"type": "array",
"items": {
"type": "object",
"properties": {
"setType": {
"type": "string",
"enum": [
"warmup",
"working"
],
"description": "Defaults to working."
},
"weight": {
"type": "object",
"properties": {
"value": {
"type": "number",
"minimum": 0
},
"unit": {
"type": "string",
"enum": [
"kg",
"lb"
]
}
},
"required": [
"value",
"unit"
],
"additionalProperties": true,
"description": "A load with its unit. Stored as kilograms."
},
"loadIntent": {
"type": "string",
"enum": [
"bar_total",
"per_hand",
"plates_each_side",
"assistance",
"added_bodyweight",
"machine_stack",
"custom"
],
"description": "What the weight means, for example per_hand for dumbbells. Omit for a plain total load."
},
"reps": {
"type": "integer",
"minimum": 0,
"maximum": 1000
},
"durationSeconds": {
"type": "number",
"minimum": 0,
"maximum": 21600,
"description": "Time this set took, in seconds. For a timed effort such as 5 km in 28 minutes, put 1680 here with distanceMeters 5000."
},
"distanceMeters": {
"type": "number",
"minimum": 0,
"maximum": 500000
},
"holdSeconds": {
"type": "number",
"minimum": 0,
"maximum": 3600
},
"intensity": {
"type": "number",
"minimum": 0,
"maximum": 10,
"description": "Effort from 0 to 10."
}
},
"additionalProperties": true
},
"minItems": 1,
"maxItems": 30
}
},
"required": [
"sets"
],
"additionalProperties": true,
"description": "One exercise with its sets. Give exerciseId or name; an unknown exercise fails with suggestions."
},
"minItems": 1,
"maxItems": 30
},
"date": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}$",
"description": "Activity Day, YYYY-MM-DD. Defaults to the workout's current date."
}
},
"required": [
"id",
"name",
"exercises"
],
"additionalProperties": true
}Output
| Field | Type | Description |
|---|---|---|
| id | string | |
| date | string (YYYY-MM-DD) | The Activity Day the workout was saved to. |
| timezone | string | IANA timezone that defines that Activity Day. |
| estimatedCaloriesoptional | number |
Full output schema
{
"type": "object",
"properties": {
"id": {
"type": "string"
},
"date": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}$",
"description": "The Activity Day the workout was saved to."
},
"timezone": {
"type": "string",
"description": "IANA timezone that defines that Activity Day."
},
"estimatedCalories": {
"type": "number",
"minimum": 0
}
},
"required": [
"id",
"date",
"timezone"
],
"additionalProperties": true
}Example request
curl -X PUT "https://api.dailygoal.fit/v1/workouts" \
-H "Authorization: Bearer $DAILYGOAL_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"id":"m1774k2j9h6g3f0d7s4a1p8o5i2u9y6t","name":"Push day","durationSeconds":3600,"notes":"Took longer rests.","exercises":[{"exerciseId":"jx71q4w7e0r3t6y9u2i5o8p1a4s7d0f3","sets":[{"setType":"warmup","weight":{"value":40,"unit":"kg"},"reps":10},{"weight":{"value":70,"unit":"kg"},"reps":8,"intensity":7},{"weight":{"value":70,"unit":"kg"},"reps":8,"intensity":8}]},{"exerciseId":"jx73e6r9t2y5u8i1o4p7a0s3d6f9g2h5","sets":[{"weight":{"value":40,"unit":"kg"},"reps":8,"intensity":7},{"weight":{"value":40,"unit":"kg"},"reps":7,"intensity":9}]}]}'{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "replace_workout",
"arguments": {
"id": "m1774k2j9h6g3f0d7s4a1p8o5i2u9y6t",
"name": "Push day",
"durationSeconds": 3600,
"notes": "Took longer rests.",
"exercises": [
{
"exerciseId": "jx71q4w7e0r3t6y9u2i5o8p1a4s7d0f3",
"sets": [
{
"setType": "warmup",
"weight": {
"value": 40,
"unit": "kg"
},
"reps": 10
},
{
"weight": {
"value": 70,
"unit": "kg"
},
"reps": 8,
"intensity": 7
},
{
"weight": {
"value": 70,
"unit": "kg"
},
"reps": 8,
"intensity": 8
}
]
},
{
"exerciseId": "jx73e6r9t2y5u8i1o4p7a0s3d6f9g2h5",
"sets": [
{
"weight": {
"value": 40,
"unit": "kg"
},
"reps": 8,
"intensity": 7
},
{
"weight": {
"value": 40,
"unit": "kg"
},
"reps": 7,
"intensity": 9
}
]
}
]
}
}
}Example response
Synthetic data. REST returns this object as the body; MCP returns it as structuredContent.
{
"id": "m1774k2j9h6g3f0d7s4a1p8o5i2u9y6t",
"date": "2026-09-14",
"timezone": "Europe/London",
"estimatedCalories": 225
}Errors
unauthorized(401)origin_not_allowed(403)misdirected_request(421)subscription_required(403)rate_limited(429)validation_failed(400)not_found(404)conflict(409)internal_error(500)
delete_workout
DELETE https://api.dailygoal.fit/v1/workouts
MCP tool delete_workout · Changes data · Destructive · DailyGoal data only
Delete a finished workout with all its exercises and sets. This cannot be undone. An explicit delete request authorizes deletion once list_workouts identifies a unique match; ask for clarification only when the target is ambiguous. To correct a workout instead, use replace_workout.
Input
| Field | Type | Description |
|---|---|---|
| id | string | Workout id from list_workouts or log_workout. |
Full input schema, including bounds and nested alternatives (MCP)
{
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "Workout id from list_workouts or log_workout."
}
},
"required": [
"id"
],
"additionalProperties": true
}Output
| Field | Type | Description |
|---|---|---|
| id | string | |
| deleted | true | |
| date | string (YYYY-MM-DD) | The Activity Day the workout was on. |
| timezone | string |
Full output schema
{
"type": "object",
"properties": {
"id": {
"type": "string"
},
"deleted": {
"type": "boolean",
"enum": [
true
]
},
"date": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}$",
"description": "The Activity Day the workout was on."
},
"timezone": {
"type": "string"
}
},
"required": [
"id",
"deleted",
"date",
"timezone"
],
"additionalProperties": true
}Example request
curl -X DELETE "https://api.dailygoal.fit/v1/workouts?id=m1775l3k0j7h4g1f8d5s2a9p6o3i0u7y" \
-H "Authorization: Bearer $DAILYGOAL_API_TOKEN"{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "delete_workout",
"arguments": {
"id": "m1775l3k0j7h4g1f8d5s2a9p6o3i0u7y"
}
}
}Example response
Synthetic data. REST returns this object as the body; MCP returns it as structuredContent.
{
"id": "m1775l3k0j7h4g1f8d5s2a9p6o3i0u7y",
"deleted": true,
"date": "2026-09-12",
"timezone": "Europe/London"
}Errors
unauthorized(401)origin_not_allowed(403)misdirected_request(421)subscription_required(403)rate_limited(429)validation_failed(400)not_found(404)conflict(409)internal_error(500)