0

Bulk mutate an organizations issues

by
Published Oct 17, 2025

Bulk mutate various attributes on a maxmimum of 1000 issues. - For non-status updates, the `id` query parameter is required. - For status updates, the `id` query parameter may be omitted to update issues that match the filtering. If any IDs are out of scope, the data won't be mutated but the endpoint will still produce a successful response. For example, if no issues were found matching the criteria, a HTTP 204 is returned.

Script sentry Verified

The script

Submitted by hugo697 Bun
Verified 235 days ago
1
//native
2
/**
3
 * Bulk mutate an organizations issues
4
 * Bulk mutate various attributes on a maxmimum of 1000 issues. 
5
- For non-status updates, the `id` query parameter is required. 
6
- For status updates, the `id` query parameter may be omitted to update issues that match the filtering. 
7
If any IDs are out of scope, the data won't be mutated but the endpoint will still produce a successful response. For example, if no issues were found matching the criteria, a HTTP 204 is returned.
8
 */
9
export async function main(
10
	auth: RT.Sentry,
11
	body: Body,
12
	environment?: string | undefined,
13
	project?: string | undefined,
14
	id?: string | undefined,
15
	query?: string | undefined,
16
	viewId?: string | undefined,
17
	sort?: 'date' | 'freq' | 'inbox' | 'new' | 'trends' | 'user' | undefined,
18
	limit?: string | undefined
19
) {
20
	const url = new URL(
21
		`https://${auth.region}.sentry.io/api/0/organizations/${auth.organizationSlug}/issues/`
22
	)
23
	for (const [k, v] of [
24
		['environment', environment],
25
		['project', project],
26
		['id', id],
27
		['query', query],
28
		['viewId', viewId],
29
		['sort', sort],
30
		['limit', limit]
31
	]) {
32
		if (v !== undefined && v !== '') {
33
			url.searchParams.append(k, v)
34
		}
35
	}
36
	const response = await fetch(url, {
37
		method: 'PUT',
38
		headers: {
39
			'Content-Type': 'application/json',
40
			Authorization: 'Bearer ' + auth.token
41
		},
42
		body: JSON.stringify(body)
43
	})
44
	if (!response.ok) {
45
		const text = await response.text()
46
		throw new Error(`${response.status} ${text}`)
47
	}
48
	return await response.json()
49
}
50

51
/* eslint-disable */
52
/**
53
 * This file was automatically generated by json-schema-to-typescript.
54
 * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,
55
 * and run json-schema-to-typescript to regenerate this file.
56
 */
57

58
export interface Body {
59
	/**
60
	 * If true, marks the issue as reviewed by the requestor.
61
	 */
62
	inbox: boolean
63
	/**
64
	 * Limit mutations to only issues with the given status.
65
	 *
66
	 * * `resolved`
67
	 * * `unresolved`
68
	 * * `ignored`
69
	 * * `resolvedInNextRelease`
70
	 * * `muted`
71
	 */
72
	status: 'resolved' | 'unresolved' | 'ignored' | 'resolvedInNextRelease' | 'muted'
73
	/**
74
	 * Additional details about the resolution. Status detail updates that include release data are only allowed for issues within a single project.
75
	 */
76
	statusDetails: {
77
		/**
78
		 * If true, marks the issue as resolved in the next release.
79
		 */
80
		inNextRelease: boolean
81
		/**
82
		 * The version of the release that the issue should be resolved in.If set to `latest`, the latest release will be used.
83
		 */
84
		inRelease: string
85
		/**
86
		 * The commit data that the issue should use for resolution.
87
		 */
88
		inCommit?: {
89
			/**
90
			 * The SHA of the resolving commit.
91
			 */
92
			commit: string
93
			/**
94
			 * The name of the repository (as it appears in Sentry).
95
			 */
96
			repository: string
97
			[k: string]: unknown
98
		}
99
		/**
100
		 * Ignore the issue until for this many minutes.
101
		 */
102
		ignoreDuration: number
103
		/**
104
		 * Ignore the issue until it has occurred this many times in `ignoreWindow` minutes.
105
		 */
106
		ignoreCount: number
107
		/**
108
		 * Ignore the issue until it has occurred `ignoreCount` times in this many minutes. (Max: 1 week)
109
		 */
110
		ignoreWindow: number
111
		/**
112
		 * Ignore the issue until it has affected this many users in `ignoreUserWindow` minutes.
113
		 */
114
		ignoreUserCount: number
115
		/**
116
		 * Ignore the issue until it has affected `ignoreUserCount` users in this many minutes. (Max: 1 week)
117
		 */
118
		ignoreUserWindow: number
119
		[k: string]: unknown
120
	}
121
	/**
122
	 * The new substatus of the issue.
123
	 *
124
	 * * `archived_until_escalating`
125
	 * * `archived_until_condition_met`
126
	 * * `archived_forever`
127
	 * * `escalating`
128
	 * * `ongoing`
129
	 * * `regressed`
130
	 * * `new`
131
	 */
132
	substatus:
133
		| 'archived_until_escalating'
134
		| 'archived_until_condition_met'
135
		| 'archived_forever'
136
		| 'escalating'
137
		| 'ongoing'
138
		| 'regressed'
139
		| 'new'
140
		| null
141
	/**
142
	 * If true, marks the issue as seen by the requestor.
143
	 */
144
	hasSeen: boolean
145
	/**
146
	 * If true, bookmarks the issue for the requestor.
147
	 */
148
	isBookmarked: boolean
149
	/**
150
	 * If true, publishes the issue.
151
	 */
152
	isPublic: boolean
153
	/**
154
	 * If true, subscribes the requestor to the issue.
155
	 */
156
	isSubscribed: boolean
157
	/**
158
	 * If true, merges the issues together.
159
	 */
160
	merge: boolean
161
	/**
162
	 * If true, discards the issues instead of updating them.
163
	 */
164
	discard: boolean
165
	/**
166
	 * The user or team that should be assigned to the issues. Values take the form of `<user_id>`, `user:<user_id>`, `<username>`, `<user_primary_email>`, or `team:<team_id>`.
167
	 */
168
	assignedTo: string
169
	/**
170
	 * The priority that should be set for the issues
171
	 *
172
	 * * `low`
173
	 * * `medium`
174
	 * * `high`
175
	 */
176
	priority: 'low' | 'medium' | 'high'
177
	[k: string]: unknown
178
}
179