Add start_date parameter to the Issue REST API
What does this MR do and why?
The start_date field is already exposed in the API response and
handled by the WorkItems::Callbacks::StartAndDueDate callback.
This adds the missing Grape parameter declaration so it can be set on create and update, and protects it behind the same set_issue_metadata permission check as due_date.
References
Screenshots or screen recordings
# Create an issue with a start date
❯ curl --request POST \
--header "PRIVATE-TOKEN: $GDK_PAT" \
--url "http://gdk.test:3000/api/v4/projects/37/issues" \
--data "title=New%20feature&start_date=2025-01-01"
{"id":723,"iid":3,"project_id":37,"title":"New feature","description":null,"state":"opened","created_at":"2026-05-27T01:24:05.041Z","updated_at":"2026-05-27T01:24:05.041Z","closed_at":null,"closed_by":null,"labels":[],"milestone":null,"assignees":[],"author":{"id":1,"username":"root","public_email":null,"name":"Administrator","state":"active","locked":false,"avatar_url":"https://www.gravatar.com/avatar/15bbd3f9e9852c9d6f0e82619c57f34c26004189add66e481c8524d6394ea445?s=80\u0026d=identicon","web_url":"http://gdk.test:3000/root"},"type":"ISSUE","assignee":null,"user_notes_count":0,"merge_requests_count":0,"upvotes":0,"downvotes":0,"start_date":"2025-01-01","due_date":null,"confidential":false,"discussion_locked":null,"issue_type":"issue","web_url":"http://gdk.test:3000/features/add-start-date-rest-api/-/work_items/3","time_stats":{"time_estimate":0,"total_time_spent":0,"human_time_estimate":null,"human_total_time_spent":null},"task_completion_status":{"count":0,"completed_count":0},"weight":null,"blocking_issues_count":0,"has_tasks":true,"task_status":"","_links":{"self":"http://gdk.test:3000/api/v4/projects/37/issues/3","notes":"http://gdk.test:3000/api/v4/projects/37/issues/3/notes","award_emoji":"http://gdk.test:3000/api/v4/projects/37/issues/3/award_emoji","project":"http://gdk.test:3000/api/v4/projects/37","closed_as_duplicate_of":null},"references":{"short":"#3","relative":"#3","full":"features/add-start-date-rest-api#3"},"severity":"UNKNOWN","subscribed":true,"moved_to_id":null,"imported":false,"imported_from":"none","service_desk_reply_to":null,"epic_iid":null,"epic":null,"iteration":null,"health_status":null}%
# Update an issue with a start date
❯ curl --request PUT \
--header "PRIVATE-TOKEN: $GDK_PAT" \
--url "http://gdk.test:3000/api/v4/projects/37/issues/3" \
--data "start_date=2025-02-01"
{"id":723,"iid":3,"project_id":37,"title":"New feature","description":null,"state":"opened","created_at":"2026-05-27T01:24:05.041Z","updated_at":"2026-05-27T01:25:27.514Z","closed_at":null,"closed_by":null,"labels":[],"milestone":null,"assignees":[],"author":{"id":1,"username":"root","public_email":null,"name":"Administrator","state":"active","locked":false,"avatar_url":"https://www.gravatar.com/avatar/15bbd3f9e9852c9d6f0e82619c57f34c26004189add66e481c8524d6394ea445?s=80\u0026d=identicon","web_url":"http://gdk.test:3000/root"},"type":"ISSUE","assignee":null,"user_notes_count":0,"merge_requests_count":0,"upvotes":0,"downvotes":0,"start_date":"2025-02-01","due_date":null,"confidential":false,"discussion_locked":null,"issue_type":"issue","web_url":"http://gdk.test:3000/features/add-start-date-rest-api/-/work_items/3","time_stats":{"time_estimate":0,"total_time_spent":0,"human_time_estimate":null,"human_total_time_spent":null},"task_completion_status":{"count":0,"completed_count":0},"weight":null,"blocking_issues_count":0,"has_tasks":true,"task_status":"","_links":{"self":"http://gdk.test:3000/api/v4/projects/37/issues/3","notes":"http://gdk.test:3000/api/v4/projects/37/issues/3/notes","award_emoji":"http://gdk.test:3000/api/v4/projects/37/issues/3/award_emoji","project":"http://gdk.test:3000/api/v4/projects/37","closed_as_duplicate_of":null},"references":{"short":"#3","relative":"#3","full":"features/add-start-date-rest-api#3"},"severity":"UNKNOWN","subscribed":true,"moved_to_id":null,"imported":false,"imported_from":"none","service_desk_reply_to":null,"epic_iid":null,"epic":null,"iteration":null,"health_status":null}%
# Update an issue without params
# This shows that start_date is one of the parameters must be provided
❯ curl --request PUT \
--header "PRIVATE-TOKEN: $GDK_PAT" \
--url "http://gdk.test:3000/api/v4/projects/37/issues/3"
{"error":"assignee_id, assignee_ids, confidential, created_at, description, discussion_locked, due_date, start_date, labels, add_labels, remove_labels, milestone_id, milestone, state_event, title, issue_type, weight, epic_id, epic_iid are missing, at least one parameter must be provided"}%How to set up and validate locally
- Switch to the
feature/add-start-date-to-issue-rest-apibranch. - Use the
curlcommands in the Screenshots or screen recordings section to validate that it works. The response should include the correctstart_datethat was initially passed in.
MR acceptance checklist
Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.
Edited by Anton Smith