Legacy endpoint migration map
Legacy endpoints do not work in IRIS v3
In v3, nginx routes every URL that is not /api/* to the frontend service, so the legacy non-/api/v2 paths never reach the backend. Calls to them fail. /api/v2 is the only supported API surface.
This page maps each legacy IRIS endpoint to its /api/v2 replacement, so integrations written against v2.4.x can be ported. Use it together with Migrating to IRIS v3.
The legacy list is derived from iris-web/source/app/blueprints/rest/ (excluding blueprints/rest/v2/). Every /api/v2 target below is checked against the backend's generated OpenAPI spec by tools/api_surface.py check-map, so a replacement listed here exists with the method shown.
Entries marked no v2 replacement
A handful of legacy endpoints have no /api/v2 equivalent yet. The capability they covered is not reachable in v3 — if you depend on one, please open an issue so it can be prioritised.
POST /…/delete/{id} also answered GET in v2.4.x
The legacy delete endpoints were registered for both GET and POST, and some integrations use the GET form. Only POST is listed below; both are gone in v3, and both map to the same DELETE /api/v2/… replacement.
Legacy → /api/v2
Cases
POST /manage/cases/add→POST /api/v2/casesGET /manage/cases/list→GET /api/v2/casesGET /manage/cases/filter→GET /api/v2/cases/filterPOST /manage/cases/close/{case_id}→POST /api/v2/cases/{identifier}/closePOST /manage/cases/reopen/{case_id}→POST /api/v2/cases/{identifier}/reopenPOST /manage/cases/delete/{case_id}→DELETE /api/v2/cases/{identifier}POST /manage/cases/update/{case_id}→PUT /api/v2/cases/{identifier}POST /case/summary/update→PUT /api/v2/cases/{identifier}POST /case/tasklog/add→ (no v2 replacement yet — tracks as follow-up)GET /case/export→ (no direct v2 replacement — see/api/v2/manage/report-templates/{identifier}/renderfor exportable reports)
Case notes
GET /case/notes/groups/list→ replaced by directory-based notes atGET /api/v2/cases/{case_identifier}/notes-directoriesGET /case/notes/groups/{group_id}→GET /api/v2/cases/{case_identifier}/notes-directories/{identifier}GET /case/notes/directories/filter→GET /api/v2/cases/{case_identifier}/notes-directoriesPOST /case/notes/groups/add→POST /api/v2/cases/{case_identifier}/notes-directoriesPOST /case/notes/directories/add→POST /api/v2/cases/{case_identifier}/notes-directoriesPOST /case/notes/groups/update/{group_id}→PUT /api/v2/cases/{case_identifier}/notes-directories/{identifier}POST /case/notes/directories/update/{directory_id}→PUT /api/v2/cases/{case_identifier}/notes-directories/{identifier}POST /case/notes/groups/delete/{group_id}→DELETE /api/v2/cases/{case_identifier}/notes-directories/{identifier}— see the note belowPOST /case/notes/directories/delete/{directory_id}→DELETE /api/v2/cases/{case_identifier}/notes-directories/{identifier}— see the note belowPOST /case/notes/add→POST /api/v2/cases/{case_identifier}/notesGET /case/notes/{note_id}→GET /api/v2/cases/{case_identifier}/notes/{identifier}POST /case/notes/update/{note_id}→PUT /api/v2/cases/{case_identifier}/notes/{identifier}POST /case/notes/delete/{note_id}→DELETE /api/v2/cases/{case_identifier}/notes/{identifier}POST /case/notes/search→GET /api/v2/cases/{case_identifier}/notes/search
Deleting a note directory is unreachable in v3.0.0-beta.1
The route is registered as notes-directories<identifier> instead of notes-directories/<identifier> (a missing / in rest/v2/case_routes/notes_directories.py), so DELETE /api/v2/cases/{case_identifier}/notes-directories/{identifier} returns 404. The listed path is the intended one and will work once the route is corrected; until then, directory deletion has no working API.
Case assets
GET /case/assets/list→GET /api/v2/cases/{case_identifier}/assetsGET /case/assets/{asset_id}→GET /api/v2/assets/{identifier}(or scoped:GET /api/v2/cases/{case_identifier}/assets/{identifier})POST /case/assets/add→POST /api/v2/cases/{case_identifier}/assetsPOST /case/assets/update/{asset_id}→PUT /api/v2/cases/{case_identifier}/assets/{identifier}POST /case/assets/delete/{asset_id}→DELETE /api/v2/cases/{case_identifier}/assets/{identifier}orDELETE /api/v2/assets/{identifier}
Case IOCs
GET /case/ioc/list→GET /api/v2/cases/{case_identifier}/iocsGET /case/ioc/{ioc_id}→GET /api/v2/iocs/{identifier}POST /case/ioc/add→POST /api/v2/cases/{case_identifier}/iocsPOST /case/ioc/delete/{ioc_id}→DELETE /api/v2/cases/{case_identifier}/iocs/{identifier}orDELETE /api/v2/iocs/{identifier}POST /case/ioc/update/{ioc_id}→PUT /api/v2/cases/{case_identifier}/iocs/{identifier}orPUT /api/v2/iocs/{identifier}
Case timeline
GET /case/timeline/events/list/filter/{asset_id}→ filter onGET /api/v2/cases/{case_identifier}/timelinesGET /case/timeline/events/list→GET /api/v2/cases/{case_identifier}/timelinesGET /case/timeline/advanced-filter→ filter onGET /api/v2/cases/{case_identifier}/timelinesGET /case/timeline/state→ (no direct v2 replacement)POST /case/timeline/events/add→POST /api/v2/cases/{case_identifier}/eventsGET /case/timeline/events/{event_id}→GET /api/v2/cases/{case_identifier}/events/{identifier}POST /case/timeline/events/update/{event_id}→PUT /api/v2/cases/{case_identifier}/events/{identifier}POST /case/timeline/events/delete/{event_id}→DELETE /api/v2/cases/{case_identifier}/events/{identifier}
Case tasks
GET /case/tasks/list→GET /api/v2/cases/{case_identifier}/tasksGET /case/tasks/{task_id}→GET /api/v2/tasks/{identifier}POST /case/tasks/delete/{task_id}→DELETE /api/v2/cases/{case_identifier}/tasks/{identifier}orDELETE /api/v2/tasks/{identifier}POST /case/tasks/add→POST /api/v2/cases/{case_identifier}/tasksPOST /case/tasks/update/{task_id}→PUT /api/v2/cases/{case_identifier}/tasks/{identifier}
Case evidences
GET /case/evidences/list→GET /api/v2/cases/{case_identifier}/evidencesPOST /case/evidences/add→POST /api/v2/cases/{case_identifier}/evidencesGET /case/evidences/{evidence_id}→GET /api/v2/cases/{case_identifier}/evidences/{identifier}POST /case/evidences/delete/{evidence_id}→DELETE /api/v2/cases/{case_identifier}/evidences/{identifier}POST /case/evidences/update/{evidence_id}→PUT /api/v2/cases/{case_identifier}/evidences/{identifier}
Comments
Legacy comments hung off the case: /case/{object_name}/{object_id}/comments/*. In v3 they hang off the commented object itself, and each object type has its own prefix — there is no single generic path to call.
| Legacy | /api/v2 |
|---|---|
POST /case/{object_name}/{object_id}/comments/add |
POST /api/v2/{object_type}/{object_identifier}/comments |
GET /case/{object_name}/{object_id}/comments/list |
GET /api/v2/{object_type}/{object_identifier}/comments |
POST /case/{object_name}/{object_id}/comments/{comment_id}/edit |
PUT /api/v2/{object_type}/{object_identifier}/comments/{identifier} |
POST /case/{object_name}/{object_id}/comments/{comment_id}/delete |
DELETE /api/v2/{object_type}/{object_identifier}/comments/{identifier} |
{object_type} is one of the following, and the identifier parameter is named after it:
| Object | Collection | Item |
|---|---|---|
| Alerts | /api/v2/alerts/{alert_identifier}/comments |
.../comments/{identifier} |
| Alert clusters | /api/v2/alert-clusters/{cluster_identifier}/comments |
.../comments/{identifier} |
| Assets | /api/v2/assets/{asset_identifier}/comments |
.../comments/{identifier} |
| Events | /api/v2/events/{event_identifier}/comments |
.../comments/{identifier} |
| Evidences | /api/v2/evidences/{evidence_identifier}/comments |
.../comments/{identifier} |
| IOCs | /api/v2/iocs/{ioc_identifier}/comments |
.../comments/{identifier} |
| Notes | /api/v2/notes/{note_identifier}/comments |
.../comments/{identifier} |
| Tasks | /api/v2/tasks/{task_identifier}/comments |
.../comments/{identifier} |
All eight support GET/POST on the collection and GET/DELETE on the item. All except alert clusters also support PUT on the item — cluster comments cannot be edited.
The legacy per-alert comment routes (/alerts/{alert_id}/comments/*) map onto the alerts row above.
Alerts
GET /alerts/{alert_id}→GET /api/v2/alerts/{identifier}GET /alerts/filter→ filter onGET /api/v2/alerts(query params)POST /alerts/add→POST /api/v2/alertsPOST /alerts/update/{alert_id}→PUT /api/v2/alerts/{identifier}POST /alerts/batch/update→ repeatedPUT /api/v2/alerts/{identifier}POST /alerts/delete/{alert_id}→DELETE /api/v2/alerts/{identifier}POST /alerts/batch/delete→ repeatedDELETE /api/v2/alerts/{identifier}POST /alerts/escalate/{alert_id}→POST /api/v2/alerts/escalate/{identifier}— per-alert escalation. Distinct fromPOST /api/v2/alert-clusters/{identifier}/escalate, which acts on clusters.POST /alerts/merge/{alert_id}→POST /api/v2/alerts/merge/{identifier}— per-alert merge. Distinct from cluster-levelPOST /api/v2/alert-clusters/{identifier}/merge.POST /alerts/unmerge/{alert_id}→POST /api/v2/alerts/unmerge/{identifier}— per-alert unmerge.POST /alerts/batch/escalate→POST /api/v2/alerts/batch/escalate— batch per-alert escalation.POST /alerts/batch/merge→POST /api/v2/alerts/batch/merge— batch per-alert merge.GET /alerts/similarities/{alert_id}→GET /api/v2/alerts/{identifier}/related-alerts
Datastore (case-level)
GET /datastore/list/tree→GET /api/v2/cases/{case_identifier}/datastore/treePOST /datastore/file/add/{parent_id}→POST /api/v2/cases/{case_identifier}/datastore/folders/{folder_identifier}/filesGET /datastore/file/info/{file_id}→GET /api/v2/cases/{case_identifier}/datastore/files/{identifier}/infoPOST /datastore/file/update/{file_id}→POST /api/v2/cases/{case_identifier}/datastore/files/{identifier}POST /datastore/file/delete/{file_id}→DELETE /api/v2/cases/{case_identifier}/datastore/files/{identifier}GET /datastore/file/view/{file_id}→GET /api/v2/cases/{case_identifier}/datastore/files/{identifier}POST /datastore/file/move/{file_id}→POST /api/v2/cases/{case_identifier}/datastore/files/{identifier}/movePOST /datastore/folder/add→POST /api/v2/cases/{case_identifier}/datastore/foldersPOST /datastore/folder/delete/{folder_id}→DELETE /api/v2/cases/{case_identifier}/datastore/folders/{identifier}POST /datastore/folder/rename/{folder_id}→POST /api/v2/cases/{case_identifier}/datastore/folders/{identifier}/renamePOST /datastore/folder/move/{folder_id}→POST /api/v2/cases/{case_identifier}/datastore/folders/{identifier}/move
DIM tasks
GET /dim/tasks/list/{rows_count}→GET /api/v2/dim-tasksGET /dim/tasks/limited-list→GET /api/v2/dim-tasksGET /dim/hooks/options/{object_type}/list→ (no direct v2 replacement — module hooks are exposed atGET /api/v2/manage/modules/hooks)POST /dim/hooks/call→ (no v2 replacement yet)
Global tasks
GET /global/tasks/list→GET /api/v2/global-tasksPOST /global/tasks/add→POST /api/v2/global-tasksPOST /global/tasks/update/{task_id}→PUT /api/v2/global-tasks/{identifier}POST /global/tasks/delete/{task_id}→DELETE /api/v2/global-tasks/{identifier}
Manage — customers
GET /manage/customers/list→GET /api/v2/manage/customersGET /manage/customers/{customer_id}→GET /api/v2/manage/customers/{identifier}POST /manage/customers/add→POST /api/v2/manage/customersPOST /manage/customers/update/{customer_id}→PUT /api/v2/manage/customers/{identifier}POST /manage/customers/delete/{customer_id}→DELETE /api/v2/manage/customers/{identifier}POST /manage/customers/{customer_id}/contacts/add→POST /api/v2/manage/customers/{identifier}/contactsPOST /manage/customers/{customer_id}/contacts/{contact_id}/update→PUT /api/v2/manage/customers/{identifier}/contacts/{contact_id}
Manage — users
GET /manage/users/list→GET /api/v2/manage/usersGET /manage/users/{user_id}→GET /api/v2/manage/users/{identifier}POST /manage/users/add→POST /api/v2/manage/usersPOST /manage/users/update/{user_id}→PUT /api/v2/manage/users/{identifier}POST /manage/users/delete/{user_id}→DELETE /api/v2/manage/users/{identifier}POST /manage/users/{user_id}/groups/update→PUT /api/v2/manage/users/{identifier}/groupsPOST /manage/users/{user_id}/cases-access/update→POST /api/v2/manage/users/{identifier}/cases-accessPOST /manage/users/{user_id}/cases-access/delete→DELETE /api/v2/manage/users/{identifier}/cases-access
Manage — groups
POST /manage/groups/add→POST /api/v2/manage/groupsPOST /manage/groups/update/{group_id}→PUT /api/v2/manage/groups/{identifier}POST /manage/groups/delete/{group_id}→DELETE /api/v2/manage/groups/{identifier}POST /manage/groups/{group_id}/members/update→PUT /api/v2/manage/groups/{identifier}/membersPOST /manage/groups/{group_id}/members/delete/{user_id}→DELETE /api/v2/manage/groups/{identifier}/members/{user_id}POST /manage/groups/{group_id}/cases-access/update→POST /api/v2/manage/groups/{identifier}/cases-accessPOST /manage/groups/{group_id}/cases-access/delete→DELETE /api/v2/manage/groups/{identifier}/cases-accessGET /manage/groups/list→GET /api/v2/manage/groups
Manage — taxonomies & object types
GET /manage/asset-type/list→GET /api/v2/manage/case-objects/asset-typesGET /manage/asset-type/{asset_type_id}→GET /api/v2/manage/case-objects/asset-types/{identifier}POST /manage/asset-type/delete/{asset_type_id}→DELETE /api/v2/manage/case-objects/asset-types/{identifier}POST /manage/asset-type/add→POST /api/v2/manage/case-objects/asset-typesPOST /manage/asset-type/update/{asset_type_id}→PUT /api/v2/manage/case-objects/asset-types/{identifier}GET /manage/task-status/list→GET /api/v2/manage/task-statusesGET /manage/task-status/{task_status_id}→ (no v2 replacement — list-only; filterGET /api/v2/manage/task-statuses)GET /manage/analysis-status/list→GET /api/v2/manage/analysis-statusesGET /manage/analysis-status/{analysis_status_id}→ (no v2 replacement — list-only; filterGET /api/v2/manage/analysis-statuses)GET /manage/ioc-types/list→GET /api/v2/manage/case-objects/ioc-typesGET /manage/ioc-types/{ioc_type_id}→GET /api/v2/manage/case-objects/ioc-types/{identifier}POST /manage/ioc-types/delete/{ioc_type_id}→DELETE /api/v2/manage/case-objects/ioc-types/{identifier}POST /manage/ioc-types/add→POST /api/v2/manage/case-objects/ioc-typesPOST /manage/ioc-types/update/{ioc_type_id}→PUT /api/v2/manage/case-objects/ioc-types/{identifier}GET /manage/tlp/list→GET /api/v2/manage/tlpGET /manage/case-classifications/list→GET /api/v2/manage/case-objects/case-classificationsGET /manage/case-classifications/{classification_id}→GET /api/v2/manage/case-objects/case-classifications/{identifier}POST /manage/case-classifications/add→POST /api/v2/manage/case-objects/case-classificationsPOST /manage/case-classifications/update/{classification_id}→PUT /api/v2/manage/case-objects/case-classifications/{identifier}POST /manage/case-classifications/delete/{classification_id}→DELETE /api/v2/manage/case-objects/case-classifications/{identifier}GET /manage/case-states/list→GET /api/v2/manage/case-objects/case-statesGET /manage/case-states/{state_id}→GET /api/v2/manage/case-objects/case-states/{identifier}POST /manage/case-states/add→POST /api/v2/manage/case-objects/case-statesPOST /manage/case-states/update/{state_id}→PUT /api/v2/manage/case-objects/case-states/{identifier}POST /manage/case-states/delete/{state_id}→DELETE /api/v2/manage/case-objects/case-states/{identifier}GET /manage/compromise-status/list→ (no direct v2 replacement; asset compromise status remains driven by fieldasset_compromise_status_id)GET /manage/severities/list→GET /api/v2/manage/severitiesGET /manage/evidence-types/list→GET /api/v2/manage/case-objects/evidence-typesGET /manage/evidence-types/{type_id}→GET /api/v2/manage/case-objects/evidence-types/{identifier}POST /manage/evidence-types/add→POST /api/v2/manage/case-objects/evidence-typesPOST /manage/evidence-types/update/{type_id}→PUT /api/v2/manage/case-objects/evidence-types/{identifier}POST /manage/evidence-types/delete/{state_id}→DELETE /api/v2/manage/case-objects/evidence-types/{identifier}GET /manage/event-categories/list→GET /api/v2/manage/event-categories
Manage — case templates
POST /manage/case-templates/add→POST /api/v2/manage/case-templatesPOST /manage/case-templates/update/{template_id}→PUT /api/v2/manage/case-templates/{identifier}POST /manage/case-templates/delete/{template_id}→DELETE /api/v2/manage/case-templates/{identifier}
Ping / versions (unchanged)
These sit under /api/ and are unaffected by the v3 routing change:
GET /api/versions— no changeGET /api/ping— no change
Legacy routes never documented in the OpenAPI spec
The audit surfaced several further legacy routes that were never in the OpenAPI spec — internal UI helpers for the old jQuery interface. They are listed here only so integrations that reached for them can find the /api/v2 equivalent; like every other legacy path, they do not work in v3. Examples:
GET /alerts/{alert_id}/comments/list,POST /alerts/{alert_id}/comments/add,.../delete,.../edit(v2 replacement is/api/v2/alerts/{alert_identifier}/comments*— see Comments)GET /case/assets/filter,/case/assets/state,POST /case/assets/uploadGET /case/evidences/stateGET /case/ioc/state,POST /case/ioc/uploadGET /case/notes/{cur_id}/revisions/*(v2 replacement is/api/v2/cases/{case_identifier}/notes/{identifier}/revisions*)GET /case/notes/state,GET /case/notes/searchGET /case/exists,GET /case/summary/fetch,GET /case/activities/list,GET /case/meta,GET /case/users/listPOST /case/access/set-group,POST /case/access/set-user,POST /case/update-status,POST /case/review/updateGET /case/tasks/state,POST /case/tasks/status/update/{cur_id}GET /case/timeline/visualize/data/by-asset,.../by-category,POST /case/timeline/events/convert-date,POST /case/timeline/events/csv_upload,GET /case/timeline/events/flag/{cur_id},GET /case/timeline/events/duplicate/{cur_id}GET /context/search-cases,POST /context/setPOST /logout,GET /dashboard/case_charts,GET /global/tasks/{cur_id},POST /user/tasks/status/updateGET /user/cases/list,GET /user/tasks/list,GET /user/reviews/listGET /datastore/list/filter,POST /datastore/file/add-interactivePOST /filters/add,POST /filters/update/{filter_id},POST /filters/delete/{filter_id},GET /filters/{filter_id},GET /filters/{filter_type}/listGET /manage/access-control/*,GET /manage/alert-status/*,GET /manage/alert-resolutions/*,GET /manage/outcome-status/list,POST /manage/analysis-status/searchGET /manage/assets/filter,POST /manage/asset-types/searchGET /manage/attributes/list,POST /manage/attributes/update/{cur_id}(v2 replacement is/api/v2/manage/custom-attributes)POST /manage/case-classifications/search,GET /manage/case-templates/list,GET /manage/cases/{identifier}POST /manage/cases/trigger-pipeline,POST /manage/cases/upload_filesGET /manage/customers/{client_id}/cases,POST /manage/customers/{client_id}/contacts/{contact_id}/deletePOST /manage/event-categories/search,POST /manage/evidence-types/search,GET /manage/groups/{cur_id},GET /manage/groups/{cur_id}/cases-access,POST /manage/ioc-types/searchGET /manage/modules/*(v2 replacement is/api/v2/manage/modules*)GET /manage/server/backups/make-db(v2:POST /api/v2/manage/server/backups/db)POST /manage/settings/update(v2:PUT /api/v2/manage/server/settings)GET /manage/severities/{severity_id},POST /manage/severities/searchGET /manage/tags/filter,GET /manage/tags/suggest(v2 replacement isGET /api/v2/tagsplusGET /api/v2/users/mentionable)GET /manage/templates/*(v2 replacement is/api/v2/manage/report-templates*)GET /manage/tlp/{cur_id}GET /manage/users/filter,POST /manage/users/{cur_id}/customers/update,GET /manage/users/{cur_id}/cases-accessGET /manage/users/deactivate/{cur_id}(v2:POST /api/v2/manage/users/{identifier}/deactivate)GET /manage/users/activate/{cur_id}(v2:POST /api/v2/manage/users/{identifier}/activate)POST /manage/users/renew-api-key/{cur_id}(v2:POST /api/v2/manage/users/{identifier}/api-key/renew)GET /manage/users/lookup/id/{cur_id},GET /manage/users/lookup/login/{login},GET /manage/users/restricted/listGET /overview/filterGET /user/token/renew(v2:POST /api/v2/me/api-key/renew),POST /user/has-permission,POST /user/update(v2:PUT /api/v2/me),GET /user/theme/set/{theme},GET /user/deletion-prompt/set/{val},GET /user/mini-sidebar/set/{val}(all now viaPUT /api/v2/me/preferences),GET /user/refresh-permissions(v2:POST /api/v2/me/permissions/refresh),GET /user/whoami(v2:GET /api/v2/auth/whoami),GET /user/is-admin(derive from/api/v2/auth/whoamipayload)GET /case/report/generate-activities/{report_id},GET /case/report/generate-investigation/{report_id}(v2:POST /api/v2/manage/report-templates/{identifier}/render)POST /search(v2:GET /api/v2/search)
If an external client depends on one of these and the /api/v2 mapping above does not cover your use case, please open an issue.