diff --git a/.generator/schemas/v2/openapi.yaml b/.generator/schemas/v2/openapi.yaml index 7d574afcf4b5..9fb443da00e6 100644 --- a/.generator/schemas/v2/openapi.yaml +++ b/.generator/schemas/v2/openapi.yaml @@ -449,7 +449,7 @@ components: type: string GetIssueIncludeQueryParameter: description: Comma-separated list of relationship objects that should be included - in the response. Possible values are `assignee`, `case`, and `team_owners`. + in the response. explode: false in: query name: include @@ -996,8 +996,7 @@ components: $ref: '#/components/schemas/ServiceDefinitionSchemaVersions' SearchIssuesIncludeQueryParameter: description: Comma-separated list of relationship objects that should be included - in the response. Possible values are `issue`, `issue.assignee`, `issue.case`, - and `issue.team_owners`. + in the response. explode: false in: query name: include @@ -17296,6 +17295,102 @@ components: - score - severity type: object + Email: + description: On-Call User Email. + example: + data: + attributes: + active: true + address: john.doe@datadoghq.com + alias: '' + formats: + - html + id: 45cd9fe5-dd96-42ad-83de-2242ea9f6efd + type: emails + properties: + data: + $ref: '#/components/schemas/EmailData' + type: object + EmailAttributes: + description: Attributes for an on-call email. + properties: + active: + description: Whether the email is currently active. + type: boolean + address: + description: Email address. + type: string + alias: + description: Optional display alias for the email. + type: string + formats: + description: Preferred content formats for notifications. + items: + $ref: '#/components/schemas/EmailFormatType' + type: array + type: object + EmailCreateRequest: + description: Request body for creating an On-Call email notification channel. + example: + data: + attributes: + active: true + address: john.doe@datadoghq.com + alias: '' + formats: + - html + type: emails + properties: + data: + $ref: '#/components/schemas/EmailData' + type: object + EmailData: + description: Data for an on-call email resource. + properties: + attributes: + $ref: '#/components/schemas/EmailAttributes' + id: + description: The email's unique identifier. + type: string + type: + $ref: '#/components/schemas/EmailType' + required: + - type + type: object + EmailFormatType: + description: Specifies the format of the e-mail that is sent for On-Call notifications + enum: + - html + - text + example: html + type: string + x-enum-varnames: + - HTML + - TEXT + EmailType: + default: emails + description: Indicates that the resource is of type 'emails'. + enum: + - emails + example: emails + type: string + x-enum-varnames: + - EMAILS + EmailUpdateRequest: + description: Request body for updating an On-Call email notification channel. + example: + data: + attributes: + active: true + address: john.doe@datadoghq.com + alias: '' + formats: + - html + type: emails + properties: + data: + $ref: '#/components/schemas/EmailData' + type: object Enabled: description: Field used to enable or disable the rule. example: true @@ -71931,6 +72026,193 @@ paths: operator: AND permissions: - on_call_write + /api/v2/on-call/users/{user_id}/notification-channels/emails: + post: + description: Create a new email notification channel for an on-call user + operationId: CreateUserEmailNotificationChannel + parameters: + - description: The user ID + in: path + name: user_id + required: true + schema: + example: 00000000-0000-0000-0000-000000000000 + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/EmailCreateRequest' + required: true + responses: + '201': + content: + application/json: + schema: + $ref: '#/components/schemas/Email' + description: Created + '400': + $ref: '#/components/responses/BadRequestResponse' + '401': + $ref: '#/components/responses/UnauthorizedResponse' + '403': + $ref: '#/components/responses/ForbiddenResponse' + '404': + $ref: '#/components/responses/NotFoundResponse' + '429': + $ref: '#/components/responses/TooManyRequestsResponse' + security: + - apiKeyAuth: [] + appKeyAuth: [] + - AuthZ: [] + summary: Create an On-Call email for a user + tags: + - On-Call + x-permission: + operator: AND + permissions: + - on_call_admin + /api/v2/on-call/users/{user_id}/notification-channels/emails/{email_id}: + delete: + description: Delete an email notification channel for an on-call user + operationId: DeleteUserEmailNotificationChannel + parameters: + - description: The user ID + in: path + name: user_id + required: true + schema: + example: 00000000-0000-0000-0000-000000000000 + type: string + - description: The email ID + in: path + name: email_id + required: true + schema: + example: 45bb8fe5-dd96-42ad-83de-2241ea9f6ffc + type: string + responses: + '204': + description: No Content + '400': + $ref: '#/components/responses/BadRequestResponse' + '401': + $ref: '#/components/responses/UnauthorizedResponse' + '403': + $ref: '#/components/responses/ForbiddenResponse' + '404': + $ref: '#/components/responses/NotFoundResponse' + '429': + $ref: '#/components/responses/TooManyRequestsResponse' + security: + - apiKeyAuth: [] + appKeyAuth: [] + - AuthZ: [] + summary: Delete an On-Call email for a user + tags: + - On-Call + x-permission: + operator: AND + permissions: + - on_call_admin + get: + description: Get an email notification channel for an on-call user + operationId: GetUserEmailNotificationChannel + parameters: + - description: The user ID + in: path + name: user_id + required: true + schema: + example: 00000000-0000-0000-0000-000000000000 + type: string + - description: The email ID + in: path + name: email_id + required: true + schema: + example: 45bb8fe5-dd96-42ad-83de-2241ea9f6ffc + type: string + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/Email' + description: OK + '400': + $ref: '#/components/responses/BadRequestResponse' + '401': + $ref: '#/components/responses/UnauthorizedResponse' + '403': + $ref: '#/components/responses/ForbiddenResponse' + '404': + $ref: '#/components/responses/NotFoundResponse' + '429': + $ref: '#/components/responses/TooManyRequestsResponse' + security: + - apiKeyAuth: [] + appKeyAuth: [] + - AuthZ: [] + summary: Get an On-Call email for a user + tags: + - On-Call + x-permission: + operator: AND + permissions: + - on_call_admin + put: + description: Update an email notification channel for an on-call user + operationId: UpdateUserEmailNotificationChannel + parameters: + - description: The user ID + in: path + name: user_id + required: true + schema: + example: 00000000-0000-0000-0000-000000000000 + type: string + - description: The email ID + in: path + name: email_id + required: true + schema: + example: 45bb8fe5-dd96-42ad-83de-2241ea9f6ffc + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/EmailUpdateRequest' + required: true + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/Email' + description: OK + '400': + $ref: '#/components/responses/BadRequestResponse' + '401': + $ref: '#/components/responses/UnauthorizedResponse' + '403': + $ref: '#/components/responses/ForbiddenResponse' + '404': + $ref: '#/components/responses/NotFoundResponse' + '429': + $ref: '#/components/responses/TooManyRequestsResponse' + security: + - apiKeyAuth: [] + appKeyAuth: [] + - AuthZ: [] + summary: Update an On-Call email for a user + tags: + - On-Call + x-permission: + operator: AND + permissions: + - on_call_admin /api/v2/org_configs: get: description: Returns all Org Configs (name, description, and value). diff --git a/cassettes/v2/On-Call_446749911/Create-an-On-Call-email-for-a-user-returns-Bad-Request-response_2287249333/frozen.json b/cassettes/v2/On-Call_446749911/Create-an-On-Call-email-for-a-user-returns-Bad-Request-response_2287249333/frozen.json new file mode 100644 index 000000000000..5fa040e6a3d5 --- /dev/null +++ b/cassettes/v2/On-Call_446749911/Create-an-On-Call-email-for-a-user-returns-Bad-Request-response_2287249333/frozen.json @@ -0,0 +1 @@ +"2025-11-12T14:36:01.432Z" diff --git a/cassettes/v2/On-Call_446749911/Create-an-On-Call-email-for-a-user-returns-Bad-Request-response_2287249333/recording.har b/cassettes/v2/On-Call_446749911/Create-an-On-Call-email-for-a-user-returns-Bad-Request-response_2287249333/recording.har new file mode 100644 index 000000000000..fcb97431c59a --- /dev/null +++ b/cassettes/v2/On-Call_446749911/Create-an-On-Call-email-for-a-user-returns-Bad-Request-response_2287249333/recording.har @@ -0,0 +1,157 @@ +{ + "log": { + "_recordingName": "On-Call/Create an On-Call email for a user returns \"Bad Request\" response", + "creator": { + "comment": "persister:fs", + "name": "Polly.JS", + "version": "6.0.5" + }, + "entries": [ + { + "_id": "8c568369eb6de9123c0e526a72812774", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 165, + "cookies": [], + "headers": [ + { + "_fromType": "array", + "name": "accept", + "value": "application/json" + }, + { + "_fromType": "array", + "name": "content-type", + "value": "application/json" + } + ], + "headersSize": 550, + "httpVersion": "HTTP/1.1", + "method": "POST", + "postData": { + "mimeType": "application/json", + "params": [], + "text": "{\"data\":{\"attributes\":{\"email\":\"Test-Create_an_On_Call_email_for_a_user_returns_Bad_Request_response-1762958161@datadoghq.com\",\"title\":\"user title\"},\"type\":\"users\"}}" + }, + "queryString": [], + "url": "https://api.datadoghq.com/api/v2/users" + }, + "response": { + "bodySize": 754, + "content": { + "mimeType": "application/json", + "size": 754, + "text": "{\"data\":{\"type\":\"users\",\"id\":\"e94824bc-bfd4-11f0-adaa-1e9e4b86ba5b\",\"attributes\":{\"name\":null,\"handle\":\"test-create_an_on_call_email_for_a_user_returns_bad_request_response-1762958161@datadoghq.com\",\"created_at\":\"2025-11-12T14:36:01.627725+00:00\",\"modified_at\":\"2025-11-12T14:36:01.627725+00:00\",\"email\":\"test-create_an_on_call_email_for_a_user_returns_bad_request_response-1762958161@datadoghq.com\",\"icon\":\"https://secure.gravatar.com/avatar/0c60562056ba523711aac984491c4445?s=48&d=retro\",\"title\":\"user title\",\"verified\":false,\"service_account\":false,\"disabled\":false,\"allowed_login_methods\":[],\"status\":\"Pending\",\"last_login_time\":null},\"relationships\":{\"roles\":{\"data\":[]},\"org\":{\"data\":{\"type\":\"orgs\",\"id\":\"4dee724d-00cc-11ea-a77b-570c9d03c6c5\"}}}}}\n" + }, + "cookies": [], + "headers": [ + { + "name": "content-type", + "value": "application/json" + } + ], + "headersSize": 681, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 201, + "statusText": "Created" + }, + "startedDateTime": "2025-11-12T14:36:01.436Z", + "time": 200 + }, + { + "_id": "abda9366a1def08d2295c1d9c6fda1ea", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 98, + "cookies": [], + "headers": [ + { + "_fromType": "array", + "name": "accept", + "value": "application/json" + }, + { + "_fromType": "array", + "name": "content-type", + "value": "application/json" + } + ], + "headersSize": 647, + "httpVersion": "HTTP/1.1", + "method": "POST", + "postData": { + "mimeType": "application/json", + "params": [], + "text": "{\"data\":{\"attributes\":{\"active\":true,\"address\":\"\",\"alias\":\"\",\"formats\":[\"html\"]},\"type\":\"emails\"}}" + }, + "queryString": [], + "url": "https://api.datadoghq.com/api/v2/on-call/users/e94824bc-bfd4-11f0-adaa-1e9e4b86ba5b/notification-channels/emails" + }, + "response": { + "bodySize": 96, + "content": { + "mimeType": "application/vnd.api+json", + "size": 96, + "text": "{\"errors\":[{\"status\":\"400\",\"title\":\"Bad Request\",\"detail\":\"attribute \\\"address\\\" is required\"}]}" + }, + "cookies": [], + "headers": [ + { + "name": "content-type", + "value": "application/vnd.api+json" + } + ], + "headersSize": 524, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 400, + "statusText": "Bad Request" + }, + "startedDateTime": "2025-11-12T14:36:01.649Z", + "time": 116 + }, + { + "_id": "7bfae60bf24c303492a50b0860f726df", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 0, + "cookies": [], + "headers": [ + { + "_fromType": "array", + "name": "accept", + "value": "*/*" + } + ], + "headersSize": 524, + "httpVersion": "HTTP/1.1", + "method": "DELETE", + "queryString": [], + "url": "https://api.datadoghq.com/api/v2/users/e94824bc-bfd4-11f0-adaa-1e9e4b86ba5b" + }, + "response": { + "bodySize": 0, + "content": { + "mimeType": "text/plain", + "size": 0 + }, + "cookies": [], + "headers": [], + "headersSize": 495, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 204, + "statusText": "No Content" + }, + "startedDateTime": "2025-11-12T14:36:01.780Z", + "time": 425 + } + ], + "pages": [], + "version": "1.2" + } +} diff --git a/cassettes/v2/On-Call_446749911/Create-an-On-Call-email-for-a-user-returns-Created-response_3646864723/frozen.json b/cassettes/v2/On-Call_446749911/Create-an-On-Call-email-for-a-user-returns-Created-response_3646864723/frozen.json new file mode 100644 index 000000000000..9788164752a0 --- /dev/null +++ b/cassettes/v2/On-Call_446749911/Create-an-On-Call-email-for-a-user-returns-Created-response_3646864723/frozen.json @@ -0,0 +1 @@ +"2025-11-12T14:50:04.706Z" diff --git a/cassettes/v2/On-Call_446749911/Create-an-On-Call-email-for-a-user-returns-Created-response_3646864723/recording.har b/cassettes/v2/On-Call_446749911/Create-an-On-Call-email-for-a-user-returns-Created-response_3646864723/recording.har new file mode 100644 index 000000000000..48954e0ac855 --- /dev/null +++ b/cassettes/v2/On-Call_446749911/Create-an-On-Call-email-for-a-user-returns-Created-response_3646864723/recording.har @@ -0,0 +1,157 @@ +{ + "log": { + "_recordingName": "On-Call/Create an On-Call email for a user returns \"Created\" response", + "creator": { + "comment": "persister:fs", + "name": "Polly.JS", + "version": "6.0.5" + }, + "entries": [ + { + "_id": "2fffc841e75cf2c77366fcfc1ad7daaa", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 161, + "cookies": [], + "headers": [ + { + "_fromType": "array", + "name": "accept", + "value": "application/json" + }, + { + "_fromType": "array", + "name": "content-type", + "value": "application/json" + } + ], + "headersSize": 550, + "httpVersion": "HTTP/1.1", + "method": "POST", + "postData": { + "mimeType": "application/json", + "params": [], + "text": "{\"data\":{\"attributes\":{\"email\":\"Test-Create_an_On_Call_email_for_a_user_returns_Created_response-1762959004@datadoghq.com\",\"title\":\"user title\"},\"type\":\"users\"}}" + }, + "queryString": [], + "url": "https://api.datadoghq.com/api/v2/users" + }, + "response": { + "bodySize": 746, + "content": { + "mimeType": "application/json", + "size": 746, + "text": "{\"data\":{\"type\":\"users\",\"id\":\"dfeeb6f4-bfd6-11f0-8d44-3ae83a1823f8\",\"attributes\":{\"name\":null,\"handle\":\"test-create_an_on_call_email_for_a_user_returns_created_response-1762959004@datadoghq.com\",\"created_at\":\"2025-11-12T14:50:04.935610+00:00\",\"modified_at\":\"2025-11-12T14:50:04.935610+00:00\",\"email\":\"test-create_an_on_call_email_for_a_user_returns_created_response-1762959004@datadoghq.com\",\"icon\":\"https://secure.gravatar.com/avatar/fec58aca7d399645eb368db42c5a3cc8?s=48&d=retro\",\"title\":\"user title\",\"verified\":false,\"service_account\":false,\"disabled\":false,\"allowed_login_methods\":[],\"status\":\"Pending\",\"last_login_time\":null},\"relationships\":{\"roles\":{\"data\":[]},\"org\":{\"data\":{\"type\":\"orgs\",\"id\":\"4dee724d-00cc-11ea-a77b-570c9d03c6c5\"}}}}}\n" + }, + "cookies": [], + "headers": [ + { + "name": "content-type", + "value": "application/json" + } + ], + "headersSize": 681, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 201, + "statusText": "Created" + }, + "startedDateTime": "2025-11-12T14:50:04.709Z", + "time": 240 + }, + { + "_id": "4ecdb8e074d411968f98d77d78e58a14", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 120, + "cookies": [], + "headers": [ + { + "_fromType": "array", + "name": "accept", + "value": "application/json" + }, + { + "_fromType": "array", + "name": "content-type", + "value": "application/json" + } + ], + "headersSize": 648, + "httpVersion": "HTTP/1.1", + "method": "POST", + "postData": { + "mimeType": "application/json", + "params": [], + "text": "{\"data\":{\"attributes\":{\"active\":true,\"address\":\"john.doe@datadoghq.com\",\"alias\":\"\",\"formats\":[\"html\"]},\"type\":\"emails\"}}" + }, + "queryString": [], + "url": "https://api.datadoghq.com/api/v2/on-call/users/dfeeb6f4-bfd6-11f0-8d44-3ae83a1823f8/notification-channels/emails" + }, + "response": { + "bodySize": 267, + "content": { + "mimeType": "application/vnd.api+json", + "size": 267, + "text": "{\"data\":{\"id\":\"13d8e241-945e-42e4-9759-f4979a3f821f\",\"type\":\"emails\",\"attributes\":{\"active\":true,\"address\":\"john.doe@datadoghq.com\",\"alias\":\"\",\"blocked\":false,\"created_at\":\"2025-11-12T14:50:05.405372Z\",\"formats\":[\"html\"],\"modified_at\":\"2025-11-12T14:50:05.405372Z\"}}}" + }, + "cookies": [], + "headers": [ + { + "name": "content-type", + "value": "application/vnd.api+json" + } + ], + "headersSize": 525, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 201, + "statusText": "Created" + }, + "startedDateTime": "2025-11-12T14:50:04.963Z", + "time": 506 + }, + { + "_id": "48b9047d7779368293bcb80e3f0fd569", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 0, + "cookies": [], + "headers": [ + { + "_fromType": "array", + "name": "accept", + "value": "*/*" + } + ], + "headersSize": 524, + "httpVersion": "HTTP/1.1", + "method": "DELETE", + "queryString": [], + "url": "https://api.datadoghq.com/api/v2/users/dfeeb6f4-bfd6-11f0-8d44-3ae83a1823f8" + }, + "response": { + "bodySize": 0, + "content": { + "mimeType": "text/plain", + "size": 0 + }, + "cookies": [], + "headers": [], + "headersSize": 495, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 204, + "statusText": "No Content" + }, + "startedDateTime": "2025-11-12T14:50:05.476Z", + "time": 350 + } + ], + "pages": [], + "version": "1.2" + } +} diff --git a/cassettes/v2/On-Call_446749911/Create-an-On-Call-email-for-a-user-returns-Not-Found-response_1548561814/frozen.json b/cassettes/v2/On-Call_446749911/Create-an-On-Call-email-for-a-user-returns-Not-Found-response_1548561814/frozen.json new file mode 100644 index 000000000000..dedbf201847a --- /dev/null +++ b/cassettes/v2/On-Call_446749911/Create-an-On-Call-email-for-a-user-returns-Not-Found-response_1548561814/frozen.json @@ -0,0 +1 @@ +"2025-11-12T14:52:55.277Z" diff --git a/cassettes/v2/On-Call_446749911/Create-an-On-Call-email-for-a-user-returns-Not-Found-response_1548561814/recording.har b/cassettes/v2/On-Call_446749911/Create-an-On-Call-email-for-a-user-returns-Not-Found-response_1548561814/recording.har new file mode 100644 index 000000000000..60c21b0f397f --- /dev/null +++ b/cassettes/v2/On-Call_446749911/Create-an-On-Call-email-for-a-user-returns-Not-Found-response_1548561814/recording.har @@ -0,0 +1,67 @@ +{ + "log": { + "_recordingName": "On-Call/Create an On-Call email for a user returns \"Not Found\" response", + "creator": { + "comment": "persister:fs", + "name": "Polly.JS", + "version": "6.0.5" + }, + "entries": [ + { + "_id": "f6f6c71a3454cd0f94fe78f09fc07672", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 120, + "cookies": [], + "headers": [ + { + "_fromType": "array", + "name": "accept", + "value": "application/json" + }, + { + "_fromType": "array", + "name": "content-type", + "value": "application/json" + } + ], + "headersSize": 648, + "httpVersion": "HTTP/1.1", + "method": "POST", + "postData": { + "mimeType": "application/json", + "params": [], + "text": "{\"data\":{\"attributes\":{\"active\":true,\"address\":\"john.doe@datadoghq.com\",\"alias\":\"\",\"formats\":[\"html\"]},\"type\":\"emails\"}}" + }, + "queryString": [], + "url": "https://api.datadoghq.com/api/v2/on-call/users/00000000-0000-0000-0000-000000000000/notification-channels/emails" + }, + "response": { + "bodySize": 102, + "content": { + "mimeType": "application/vnd.api+json", + "size": 102, + "text": "{\"errors\":[{\"title\":\"Generic Error\",\"detail\":\"user[00000000-0000-0000-0000-000000000000] not found\"}]}" + }, + "cookies": [], + "headers": [ + { + "name": "content-type", + "value": "application/vnd.api+json" + } + ], + "headersSize": 525, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 404, + "statusText": "Not Found" + }, + "startedDateTime": "2025-11-12T14:52:55.281Z", + "time": 165 + } + ], + "pages": [], + "version": "1.2" + } +} diff --git a/cassettes/v2/On-Call_446749911/Delete-an-On-Call-email-for-a-missing-email-returns-Not-Found-response_2592091528/frozen.json b/cassettes/v2/On-Call_446749911/Delete-an-On-Call-email-for-a-missing-email-returns-Not-Found-response_2592091528/frozen.json new file mode 100644 index 000000000000..1129a446b17e --- /dev/null +++ b/cassettes/v2/On-Call_446749911/Delete-an-On-Call-email-for-a-missing-email-returns-Not-Found-response_2592091528/frozen.json @@ -0,0 +1 @@ +"2025-11-12T15:37:07.209Z" diff --git a/cassettes/v2/On-Call_446749911/Delete-an-On-Call-email-for-a-missing-email-returns-Not-Found-response_2592091528/recording.har b/cassettes/v2/On-Call_446749911/Delete-an-On-Call-email-for-a-missing-email-returns-Not-Found-response_2592091528/recording.har new file mode 100644 index 000000000000..3ee2f8e644fc --- /dev/null +++ b/cassettes/v2/On-Call_446749911/Delete-an-On-Call-email-for-a-missing-email-returns-Not-Found-response_2592091528/recording.har @@ -0,0 +1,147 @@ +{ + "log": { + "_recordingName": "On-Call/Delete an On-Call email for a missing email returns \"Not Found\" response", + "creator": { + "comment": "persister:fs", + "name": "Polly.JS", + "version": "6.0.5" + }, + "entries": [ + { + "_id": "649013f12585ad76470a2e65014b723b", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 172, + "cookies": [], + "headers": [ + { + "_fromType": "array", + "name": "accept", + "value": "application/json" + }, + { + "_fromType": "array", + "name": "content-type", + "value": "application/json" + } + ], + "headersSize": 550, + "httpVersion": "HTTP/1.1", + "method": "POST", + "postData": { + "mimeType": "application/json", + "params": [], + "text": "{\"data\":{\"attributes\":{\"email\":\"Test-Delete_an_On_Call_email_for_a_missing_email_returns_Not_Found_response-1762961827@datadoghq.com\",\"title\":\"user title\"},\"type\":\"users\"}}" + }, + "queryString": [], + "url": "https://api.datadoghq.com/api/v2/users" + }, + "response": { + "bodySize": 768, + "content": { + "mimeType": "application/json", + "size": 768, + "text": "{\"data\":{\"type\":\"users\",\"id\":\"72452250-bfdd-11f0-bb7a-1a91fccbd64f\",\"attributes\":{\"name\":null,\"handle\":\"test-delete_an_on_call_email_for_a_missing_email_returns_not_found_response-1762961827@datadoghq.com\",\"created_at\":\"2025-11-12T15:37:07.429696+00:00\",\"modified_at\":\"2025-11-12T15:37:07.429696+00:00\",\"email\":\"test-delete_an_on_call_email_for_a_missing_email_returns_not_found_response-1762961827@datadoghq.com\",\"icon\":\"https://secure.gravatar.com/avatar/baf7b7d23e8f0bb01a4291b4a70d9fc8?s=48&d=retro\",\"title\":\"user title\",\"verified\":false,\"service_account\":false,\"disabled\":false,\"allowed_login_methods\":[],\"status\":\"Pending\",\"last_login_time\":null},\"relationships\":{\"roles\":{\"data\":[]},\"org\":{\"data\":{\"type\":\"orgs\",\"id\":\"4dee724d-00cc-11ea-a77b-570c9d03c6c5\"}}}}}\n" + }, + "cookies": [], + "headers": [ + { + "name": "content-type", + "value": "application/json" + } + ], + "headersSize": 681, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 201, + "statusText": "Created" + }, + "startedDateTime": "2025-11-12T15:37:07.213Z", + "time": 210 + }, + { + "_id": "5759f8ed39e8c8ef4547858a4267497e", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 0, + "cookies": [], + "headers": [ + { + "_fromType": "array", + "name": "accept", + "value": "*/*" + } + ], + "headersSize": 621, + "httpVersion": "HTTP/1.1", + "method": "DELETE", + "queryString": [], + "url": "https://api.datadoghq.com/api/v2/on-call/users/72452250-bfdd-11f0-bb7a-1a91fccbd64f/notification-channels/emails/00000000-0000-0000-0000-000000000000" + }, + "response": { + "bodySize": 76, + "content": { + "mimeType": "application/vnd.api+json", + "size": 76, + "text": "{\"errors\":[{\"status\":\"404\",\"title\":\"Not Found\",\"detail\":\"Email not found\"}]}" + }, + "cookies": [], + "headers": [ + { + "name": "content-type", + "value": "application/vnd.api+json" + } + ], + "headersSize": 524, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 404, + "statusText": "Not Found" + }, + "startedDateTime": "2025-11-12T15:37:07.436Z", + "time": 105 + }, + { + "_id": "c3e66d6d7f74e05414c7e0a26e63caa2", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 0, + "cookies": [], + "headers": [ + { + "_fromType": "array", + "name": "accept", + "value": "*/*" + } + ], + "headersSize": 524, + "httpVersion": "HTTP/1.1", + "method": "DELETE", + "queryString": [], + "url": "https://api.datadoghq.com/api/v2/users/72452250-bfdd-11f0-bb7a-1a91fccbd64f" + }, + "response": { + "bodySize": 0, + "content": { + "mimeType": "text/plain", + "size": 0 + }, + "cookies": [], + "headers": [], + "headersSize": 495, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 204, + "statusText": "No Content" + }, + "startedDateTime": "2025-11-12T15:37:07.552Z", + "time": 1487 + } + ], + "pages": [], + "version": "1.2" + } +} diff --git a/cassettes/v2/On-Call_446749911/Delete-an-On-Call-email-for-a-missing-user-returns-Not-Found-response_3275987947/frozen.json b/cassettes/v2/On-Call_446749911/Delete-an-On-Call-email-for-a-missing-user-returns-Not-Found-response_3275987947/frozen.json new file mode 100644 index 000000000000..34b40b414158 --- /dev/null +++ b/cassettes/v2/On-Call_446749911/Delete-an-On-Call-email-for-a-missing-user-returns-Not-Found-response_3275987947/frozen.json @@ -0,0 +1 @@ +"2025-11-12T15:08:49.844Z" diff --git a/cassettes/v2/On-Call_446749911/Delete-an-On-Call-email-for-a-missing-user-returns-Not-Found-response_3275987947/recording.har b/cassettes/v2/On-Call_446749911/Delete-an-On-Call-email-for-a-missing-user-returns-Not-Found-response_3275987947/recording.har new file mode 100644 index 000000000000..9ae0072aaec9 --- /dev/null +++ b/cassettes/v2/On-Call_446749911/Delete-an-On-Call-email-for-a-missing-user-returns-Not-Found-response_3275987947/recording.har @@ -0,0 +1,57 @@ +{ + "log": { + "_recordingName": "On-Call/Delete an On-Call email for a missing user returns \"Not Found\" response", + "creator": { + "comment": "persister:fs", + "name": "Polly.JS", + "version": "6.0.5" + }, + "entries": [ + { + "_id": "58bad44fa83968071f37b2d08db05ab3", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 0, + "cookies": [], + "headers": [ + { + "_fromType": "array", + "name": "accept", + "value": "*/*" + } + ], + "headersSize": 621, + "httpVersion": "HTTP/1.1", + "method": "DELETE", + "queryString": [], + "url": "https://api.datadoghq.com/api/v2/on-call/users/00000000-0000-0000-0000-000000000000/notification-channels/emails/00000000-0000-0000-0000-000000000000" + }, + "response": { + "bodySize": 102, + "content": { + "mimeType": "application/vnd.api+json", + "size": 102, + "text": "{\"errors\":[{\"title\":\"Generic Error\",\"detail\":\"user[00000000-0000-0000-0000-000000000000] not found\"}]}" + }, + "cookies": [], + "headers": [ + { + "name": "content-type", + "value": "application/vnd.api+json" + } + ], + "headersSize": 525, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 404, + "statusText": "Not Found" + }, + "startedDateTime": "2025-11-12T15:08:49.848Z", + "time": 116 + } + ], + "pages": [], + "version": "1.2" + } +} diff --git a/cassettes/v2/On-Call_446749911/Delete-an-On-Call-email-for-a-user-returns-No-Content-response_3573452034/frozen.json b/cassettes/v2/On-Call_446749911/Delete-an-On-Call-email-for-a-user-returns-No-Content-response_3573452034/frozen.json new file mode 100644 index 000000000000..6688323e6ab2 --- /dev/null +++ b/cassettes/v2/On-Call_446749911/Delete-an-On-Call-email-for-a-user-returns-No-Content-response_3573452034/frozen.json @@ -0,0 +1 @@ +"2025-11-11T21:34:54.765Z" diff --git a/cassettes/v2/On-Call_446749911/Delete-an-On-Call-email-for-a-user-returns-No-Content-response_3573452034/recording.har b/cassettes/v2/On-Call_446749911/Delete-an-On-Call-email-for-a-user-returns-No-Content-response_3573452034/recording.har new file mode 100644 index 000000000000..ca1bc22d81c8 --- /dev/null +++ b/cassettes/v2/On-Call_446749911/Delete-an-On-Call-email-for-a-user-returns-No-Content-response_3573452034/recording.har @@ -0,0 +1,194 @@ +{ + "log": { + "_recordingName": "On-Call/Delete an On-Call email for a user returns \"No Content\" response", + "creator": { + "comment": "persister:fs", + "name": "Polly.JS", + "version": "6.0.5" + }, + "entries": [ + { + "_id": "bf3f1119c260d109e155d8a1c11ad6c0", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 164, + "cookies": [], + "headers": [ + { + "_fromType": "array", + "name": "accept", + "value": "application/json" + }, + { + "_fromType": "array", + "name": "content-type", + "value": "application/json" + } + ], + "headersSize": 550, + "httpVersion": "HTTP/1.1", + "method": "POST", + "postData": { + "mimeType": "application/json", + "params": [], + "text": "{\"data\":{\"attributes\":{\"email\":\"Test-Delete_an_On_Call_email_for_a_user_returns_No_Content_response-1762896894@datadoghq.com\",\"title\":\"user title\"},\"type\":\"users\"}}" + }, + "queryString": [], + "url": "https://api.datadoghq.com/api/v2/users" + }, + "response": { + "bodySize": 752, + "content": { + "mimeType": "application/json", + "size": 752, + "text": "{\"data\":{\"type\":\"users\",\"id\":\"43acb848-bf46-11f0-ab62-92ea5df1f825\",\"attributes\":{\"name\":null,\"handle\":\"test-delete_an_on_call_email_for_a_user_returns_no_content_response-1762896894@datadoghq.com\",\"created_at\":\"2025-11-11T21:34:55.249474+00:00\",\"modified_at\":\"2025-11-11T21:34:55.249474+00:00\",\"email\":\"test-delete_an_on_call_email_for_a_user_returns_no_content_response-1762896894@datadoghq.com\",\"icon\":\"https://secure.gravatar.com/avatar/59021cfaece7e71bf1d358fffc29d134?s=48&d=retro\",\"title\":\"user title\",\"verified\":false,\"service_account\":false,\"disabled\":false,\"allowed_login_methods\":[],\"status\":\"Pending\",\"last_login_time\":null},\"relationships\":{\"roles\":{\"data\":[]},\"org\":{\"data\":{\"type\":\"orgs\",\"id\":\"4dee724d-00cc-11ea-a77b-570c9d03c6c5\"}}}}}\n" + }, + "cookies": [], + "headers": [ + { + "name": "content-type", + "value": "application/json" + } + ], + "headersSize": 680, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 201, + "statusText": "Created" + }, + "startedDateTime": "2025-11-11T21:34:54.769Z", + "time": 231 + }, + { + "_id": "c9968f2ac9894411b58ea9950a5417bf", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 190, + "cookies": [], + "headers": [ + { + "_fromType": "array", + "name": "accept", + "value": "application/json" + }, + { + "_fromType": "array", + "name": "content-type", + "value": "application/json" + } + ], + "headersSize": 648, + "httpVersion": "HTTP/1.1", + "method": "POST", + "postData": { + "mimeType": "application/json", + "params": [], + "text": "{\"data\":{\"attributes\":{\"active\":true,\"address\":\"test-delete_an_on_call_email_for_a_user_returns_no_content_response-1762896894@datadoghq.com\",\"alias\":\"\",\"formats\":[\"html\"]},\"type\":\"emails\"}}" + }, + "queryString": [], + "url": "https://api.datadoghq.com/api/v2/on-call/users/43acb848-bf46-11f0-ab62-92ea5df1f825/notification-channels/emails" + }, + "response": { + "bodySize": 337, + "content": { + "mimeType": "application/vnd.api+json", + "size": 337, + "text": "{\"data\":{\"id\":\"b9099fbc-43b3-4c74-9942-15ca0bcf519c\",\"type\":\"emails\",\"attributes\":{\"active\":true,\"address\":\"test-delete_an_on_call_email_for_a_user_returns_no_content_response-1762896894@datadoghq.com\",\"alias\":\"\",\"blocked\":false,\"created_at\":\"2025-11-11T21:34:55.795766Z\",\"formats\":[\"html\"],\"modified_at\":\"2025-11-11T21:34:55.795766Z\"}}}" + }, + "cookies": [], + "headers": [ + { + "name": "content-type", + "value": "application/vnd.api+json" + } + ], + "headersSize": 525, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 201, + "statusText": "Created" + }, + "startedDateTime": "2025-11-11T21:34:55.015Z", + "time": 494 + }, + { + "_id": "73534b2446a97d945d1cad3d599233cc", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 0, + "cookies": [], + "headers": [ + { + "_fromType": "array", + "name": "accept", + "value": "*/*" + } + ], + "headersSize": 621, + "httpVersion": "HTTP/1.1", + "method": "DELETE", + "queryString": [], + "url": "https://api.datadoghq.com/api/v2/on-call/users/43acb848-bf46-11f0-ab62-92ea5df1f825/notification-channels/emails/b9099fbc-43b3-4c74-9942-15ca0bcf519c" + }, + "response": { + "bodySize": 0, + "content": { + "mimeType": "text/plain", + "size": 0 + }, + "cookies": [], + "headers": [], + "headersSize": 464, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 204, + "statusText": "No Content" + }, + "startedDateTime": "2025-11-11T21:34:55.521Z", + "time": 187 + }, + { + "_id": "d240f2f5d1b7dd10e9059695bf6ff297", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 0, + "cookies": [], + "headers": [ + { + "_fromType": "array", + "name": "accept", + "value": "*/*" + } + ], + "headersSize": 524, + "httpVersion": "HTTP/1.1", + "method": "DELETE", + "queryString": [], + "url": "https://api.datadoghq.com/api/v2/users/43acb848-bf46-11f0-ab62-92ea5df1f825" + }, + "response": { + "bodySize": 0, + "content": { + "mimeType": "text/plain", + "size": 0 + }, + "cookies": [], + "headers": [], + "headersSize": 495, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 204, + "statusText": "No Content" + }, + "startedDateTime": "2025-11-11T21:34:55.721Z", + "time": 555 + } + ], + "pages": [], + "version": "1.2" + } +} diff --git a/cassettes/v2/On-Call_446749911/Get-an-On-Call-email-for-a-user-returns-OK-response_2794403011/frozen.json b/cassettes/v2/On-Call_446749911/Get-an-On-Call-email-for-a-user-returns-OK-response_2794403011/frozen.json new file mode 100644 index 000000000000..04b2aab193b6 --- /dev/null +++ b/cassettes/v2/On-Call_446749911/Get-an-On-Call-email-for-a-user-returns-OK-response_2794403011/frozen.json @@ -0,0 +1 @@ +"2025-11-12T15:45:28.077Z" diff --git a/cassettes/v2/On-Call_446749911/Get-an-On-Call-email-for-a-user-returns-OK-response_2794403011/recording.har b/cassettes/v2/On-Call_446749911/Get-an-On-Call-email-for-a-user-returns-OK-response_2794403011/recording.har new file mode 100644 index 000000000000..7f5d64f6bb29 --- /dev/null +++ b/cassettes/v2/On-Call_446749911/Get-an-On-Call-email-for-a-user-returns-OK-response_2794403011/recording.har @@ -0,0 +1,200 @@ +{ + "log": { + "_recordingName": "On-Call/Get an On-Call email for a user returns \"OK\" response", + "creator": { + "comment": "persister:fs", + "name": "Polly.JS", + "version": "6.0.5" + }, + "entries": [ + { + "_id": "d04e56f7f30710cc68c8a83914c21f7f", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 153, + "cookies": [], + "headers": [ + { + "_fromType": "array", + "name": "accept", + "value": "application/json" + }, + { + "_fromType": "array", + "name": "content-type", + "value": "application/json" + } + ], + "headersSize": 550, + "httpVersion": "HTTP/1.1", + "method": "POST", + "postData": { + "mimeType": "application/json", + "params": [], + "text": "{\"data\":{\"attributes\":{\"email\":\"Test-Get_an_On_Call_email_for_a_user_returns_OK_response-1762962328@datadoghq.com\",\"title\":\"user title\"},\"type\":\"users\"}}" + }, + "queryString": [], + "url": "https://api.datadoghq.com/api/v2/users" + }, + "response": { + "bodySize": 730, + "content": { + "mimeType": "application/json", + "size": 730, + "text": "{\"data\":{\"type\":\"users\",\"id\":\"9cd4f6e1-bfde-11f0-a1ee-1630341c9b2e\",\"attributes\":{\"name\":null,\"handle\":\"test-get_an_on_call_email_for_a_user_returns_ok_response-1762962328@datadoghq.com\",\"created_at\":\"2025-11-12T15:45:28.333343+00:00\",\"modified_at\":\"2025-11-12T15:45:28.333343+00:00\",\"email\":\"test-get_an_on_call_email_for_a_user_returns_ok_response-1762962328@datadoghq.com\",\"icon\":\"https://secure.gravatar.com/avatar/9b6db90223b9ab60eead905163035fb3?s=48&d=retro\",\"title\":\"user title\",\"verified\":false,\"service_account\":false,\"disabled\":false,\"allowed_login_methods\":[],\"status\":\"Pending\",\"last_login_time\":null},\"relationships\":{\"roles\":{\"data\":[]},\"org\":{\"data\":{\"type\":\"orgs\",\"id\":\"4dee724d-00cc-11ea-a77b-570c9d03c6c5\"}}}}}\n" + }, + "cookies": [], + "headers": [ + { + "name": "content-type", + "value": "application/json" + } + ], + "headersSize": 681, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 201, + "statusText": "Created" + }, + "startedDateTime": "2025-11-12T15:45:28.081Z", + "time": 241 + }, + { + "_id": "aea272f4c9a36a4ae3d2cbf9aedb2d4e", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 179, + "cookies": [], + "headers": [ + { + "_fromType": "array", + "name": "accept", + "value": "application/json" + }, + { + "_fromType": "array", + "name": "content-type", + "value": "application/json" + } + ], + "headersSize": 648, + "httpVersion": "HTTP/1.1", + "method": "POST", + "postData": { + "mimeType": "application/json", + "params": [], + "text": "{\"data\":{\"attributes\":{\"active\":true,\"address\":\"test-get_an_on_call_email_for_a_user_returns_ok_response-1762962328@datadoghq.com\",\"alias\":\"\",\"formats\":[\"html\"]},\"type\":\"emails\"}}" + }, + "queryString": [], + "url": "https://api.datadoghq.com/api/v2/on-call/users/9cd4f6e1-bfde-11f0-a1ee-1630341c9b2e/notification-channels/emails" + }, + "response": { + "bodySize": 326, + "content": { + "mimeType": "application/vnd.api+json", + "size": 326, + "text": "{\"data\":{\"id\":\"0b0453b5-2f4c-49c3-94d9-c3db2d5ed69c\",\"type\":\"emails\",\"attributes\":{\"active\":true,\"address\":\"test-get_an_on_call_email_for_a_user_returns_ok_response-1762962328@datadoghq.com\",\"alias\":\"\",\"blocked\":false,\"created_at\":\"2025-11-12T15:45:28.530651Z\",\"formats\":[\"html\"],\"modified_at\":\"2025-11-12T15:45:28.530651Z\"}}}" + }, + "cookies": [], + "headers": [ + { + "name": "content-type", + "value": "application/vnd.api+json" + } + ], + "headersSize": 525, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 201, + "statusText": "Created" + }, + "startedDateTime": "2025-11-12T15:45:28.332Z", + "time": 146 + }, + { + "_id": "5bdf5288e5bdc2cb7ea46918d810358f", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 0, + "cookies": [], + "headers": [ + { + "_fromType": "array", + "name": "accept", + "value": "application/json" + } + ], + "headersSize": 628, + "httpVersion": "HTTP/1.1", + "method": "GET", + "queryString": [], + "url": "https://api.datadoghq.com/api/v2/on-call/users/9cd4f6e1-bfde-11f0-a1ee-1630341c9b2e/notification-channels/emails/0b0453b5-2f4c-49c3-94d9-c3db2d5ed69c" + }, + "response": { + "bodySize": 326, + "content": { + "mimeType": "application/vnd.api+json", + "size": 326, + "text": "{\"data\":{\"id\":\"0b0453b5-2f4c-49c3-94d9-c3db2d5ed69c\",\"type\":\"emails\",\"attributes\":{\"active\":true,\"address\":\"test-get_an_on_call_email_for_a_user_returns_ok_response-1762962328@datadoghq.com\",\"alias\":\"\",\"blocked\":false,\"created_at\":\"2025-11-12T15:45:28.530651Z\",\"formats\":[\"html\"],\"modified_at\":\"2025-11-12T15:45:28.530651Z\"}}}" + }, + "cookies": [], + "headers": [ + { + "name": "content-type", + "value": "application/vnd.api+json" + } + ], + "headersSize": 525, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2025-11-12T15:45:28.488Z", + "time": 135 + }, + { + "_id": "aba7a38648fe1bb7cdaeedcbfadc4bd1", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 0, + "cookies": [], + "headers": [ + { + "_fromType": "array", + "name": "accept", + "value": "*/*" + } + ], + "headersSize": 524, + "httpVersion": "HTTP/1.1", + "method": "DELETE", + "queryString": [], + "url": "https://api.datadoghq.com/api/v2/users/9cd4f6e1-bfde-11f0-a1ee-1630341c9b2e" + }, + "response": { + "bodySize": 0, + "content": { + "mimeType": "text/plain", + "size": 0 + }, + "cookies": [], + "headers": [], + "headersSize": 495, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 204, + "statusText": "No Content" + }, + "startedDateTime": "2025-11-12T15:45:28.634Z", + "time": 208 + } + ], + "pages": [], + "version": "1.2" + } +} diff --git a/cassettes/v2/On-Call_446749911/Update-an-On-Call-email-for-a-user-returns-OK-response_649761660/frozen.json b/cassettes/v2/On-Call_446749911/Update-an-On-Call-email-for-a-user-returns-OK-response_649761660/frozen.json new file mode 100644 index 000000000000..6f3cecbf7000 --- /dev/null +++ b/cassettes/v2/On-Call_446749911/Update-an-On-Call-email-for-a-user-returns-OK-response_649761660/frozen.json @@ -0,0 +1 @@ +"2025-11-12T16:13:45.397Z" diff --git a/cassettes/v2/On-Call_446749911/Update-an-On-Call-email-for-a-user-returns-OK-response_649761660/recording.har b/cassettes/v2/On-Call_446749911/Update-an-On-Call-email-for-a-user-returns-OK-response_649761660/recording.har new file mode 100644 index 000000000000..db7eb67bb462 --- /dev/null +++ b/cassettes/v2/On-Call_446749911/Update-an-On-Call-email-for-a-user-returns-OK-response_649761660/recording.har @@ -0,0 +1,210 @@ +{ + "log": { + "_recordingName": "On-Call/Update an On-Call email for a user returns \"OK\" response", + "creator": { + "comment": "persister:fs", + "name": "Polly.JS", + "version": "6.0.5" + }, + "entries": [ + { + "_id": "713f4fb3b44daf29c9ff9825fe47f0b6", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 156, + "cookies": [], + "headers": [ + { + "_fromType": "array", + "name": "accept", + "value": "application/json" + }, + { + "_fromType": "array", + "name": "content-type", + "value": "application/json" + } + ], + "headersSize": 550, + "httpVersion": "HTTP/1.1", + "method": "POST", + "postData": { + "mimeType": "application/json", + "params": [], + "text": "{\"data\":{\"attributes\":{\"email\":\"Test-Update_an_On_Call_email_for_a_user_returns_OK_response-1762964025@datadoghq.com\",\"title\":\"user title\"},\"type\":\"users\"}}" + }, + "queryString": [], + "url": "https://api.datadoghq.com/api/v2/users" + }, + "response": { + "bodySize": 736, + "content": { + "mimeType": "application/json", + "size": 736, + "text": "{\"data\":{\"type\":\"users\",\"id\":\"9079b462-bfe2-11f0-a49d-e64699b8fdba\",\"attributes\":{\"name\":null,\"handle\":\"test-update_an_on_call_email_for_a_user_returns_ok_response-1762964025@datadoghq.com\",\"created_at\":\"2025-11-12T16:13:45.589524+00:00\",\"modified_at\":\"2025-11-12T16:13:45.589524+00:00\",\"email\":\"test-update_an_on_call_email_for_a_user_returns_ok_response-1762964025@datadoghq.com\",\"icon\":\"https://secure.gravatar.com/avatar/4b60f346cb0c28a61ac9db60531c8446?s=48&d=retro\",\"title\":\"user title\",\"verified\":false,\"service_account\":false,\"disabled\":false,\"allowed_login_methods\":[],\"status\":\"Pending\",\"last_login_time\":null},\"relationships\":{\"roles\":{\"data\":[]},\"org\":{\"data\":{\"type\":\"orgs\",\"id\":\"4dee724d-00cc-11ea-a77b-570c9d03c6c5\"}}}}}\n" + }, + "cookies": [], + "headers": [ + { + "name": "content-type", + "value": "application/json" + } + ], + "headersSize": 681, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 201, + "statusText": "Created" + }, + "startedDateTime": "2025-11-12T16:13:45.402Z", + "time": 239 + }, + { + "_id": "c3f852770d9090d8dc5e6fe34a4bddc7", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 182, + "cookies": [], + "headers": [ + { + "_fromType": "array", + "name": "accept", + "value": "application/json" + }, + { + "_fromType": "array", + "name": "content-type", + "value": "application/json" + } + ], + "headersSize": 648, + "httpVersion": "HTTP/1.1", + "method": "POST", + "postData": { + "mimeType": "application/json", + "params": [], + "text": "{\"data\":{\"attributes\":{\"active\":true,\"address\":\"test-update_an_on_call_email_for_a_user_returns_ok_response-1762964025@datadoghq.com\",\"alias\":\"\",\"formats\":[\"html\"]},\"type\":\"emails\"}}" + }, + "queryString": [], + "url": "https://api.datadoghq.com/api/v2/on-call/users/9079b462-bfe2-11f0-a49d-e64699b8fdba/notification-channels/emails" + }, + "response": { + "bodySize": 329, + "content": { + "mimeType": "application/vnd.api+json", + "size": 329, + "text": "{\"data\":{\"id\":\"9a61f64e-3092-4654-ac91-5f0ffdaf96cb\",\"type\":\"emails\",\"attributes\":{\"active\":true,\"address\":\"test-update_an_on_call_email_for_a_user_returns_ok_response-1762964025@datadoghq.com\",\"alias\":\"\",\"blocked\":false,\"created_at\":\"2025-11-12T16:13:45.834889Z\",\"formats\":[\"html\"],\"modified_at\":\"2025-11-12T16:13:45.834889Z\"}}}" + }, + "cookies": [], + "headers": [ + { + "name": "content-type", + "value": "application/vnd.api+json" + } + ], + "headersSize": 525, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 201, + "statusText": "Created" + }, + "startedDateTime": "2025-11-12T16:13:45.657Z", + "time": 155 + }, + { + "_id": "7f01f7fe9c5cf6cc2ab16aae281294ab", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 302, + "cookies": [], + "headers": [ + { + "_fromType": "array", + "name": "accept", + "value": "application/json" + }, + { + "_fromType": "array", + "name": "content-type", + "value": "application/json" + } + ], + "headersSize": 684, + "httpVersion": "HTTP/1.1", + "method": "PUT", + "postData": { + "mimeType": "application/json", + "params": [], + "text": "{\"data\":{\"attributes\":{\"active\":true,\"address\":\"test-update_an_on_call_email_for_a_user_returns_ok_response-1762964025@datadoghq.com\",\"alias\":\"Test-Update_an_On_Call_email_for_a_user_returns_OK_response-1762964025-alias\",\"formats\":[\"html\"]},\"id\":\"9a61f64e-3092-4654-ac91-5f0ffdaf96cb\",\"type\":\"emails\"}}" + }, + "queryString": [], + "url": "https://api.datadoghq.com/api/v2/on-call/users/9079b462-bfe2-11f0-a49d-e64699b8fdba/notification-channels/emails/9a61f64e-3092-4654-ac91-5f0ffdaf96cb" + }, + "response": { + "bodySize": 405, + "content": { + "mimeType": "application/vnd.api+json", + "size": 405, + "text": "{\"data\":{\"id\":\"9a61f64e-3092-4654-ac91-5f0ffdaf96cb\",\"type\":\"emails\",\"attributes\":{\"active\":true,\"address\":\"test-update_an_on_call_email_for_a_user_returns_ok_response-1762964025@datadoghq.com\",\"alias\":\"Test-Update_an_On_Call_email_for_a_user_returns_OK_response-1762964025-alias\",\"blocked\":false,\"created_at\":\"2025-11-12T16:13:45.834889Z\",\"formats\":[\"html\"],\"modified_at\":\"2025-11-12T16:13:45.925234Z\"}}}" + }, + "cookies": [], + "headers": [ + { + "name": "content-type", + "value": "application/vnd.api+json" + } + ], + "headersSize": 525, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2025-11-12T16:13:45.824Z", + "time": 78 + }, + { + "_id": "6c79faf10e1addefff28274e9f7e8bea", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 0, + "cookies": [], + "headers": [ + { + "_fromType": "array", + "name": "accept", + "value": "*/*" + } + ], + "headersSize": 524, + "httpVersion": "HTTP/1.1", + "method": "DELETE", + "queryString": [], + "url": "https://api.datadoghq.com/api/v2/users/9079b462-bfe2-11f0-a49d-e64699b8fdba" + }, + "response": { + "bodySize": 0, + "content": { + "mimeType": "text/plain", + "size": 0 + }, + "cookies": [], + "headers": [], + "headersSize": 495, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 204, + "statusText": "No Content" + }, + "startedDateTime": "2025-11-12T16:13:45.913Z", + "time": 284 + } + ], + "pages": [], + "version": "1.2" + } +} diff --git a/features/v2/given.json b/features/v2/given.json index 4ee7b3a6f955..508e0bee160e 100644 --- a/features/v2/given.json +++ b/features/v2/given.json @@ -743,6 +743,22 @@ "tag": "On-Call", "operationId": "SetOnCallTeamRoutingRules" }, + { + "parameters": [ + { + "name": "user_id", + "source": "user.data.id" + }, + { + "name": "body", + "value": "{\n \"data\": {\n \"attributes\": {\n \"active\": true,\n \"address\": \"{{ user.data.attributes.email }}\",\n \"alias\": \"\",\n \"formats\": [\n \"html\"\n ]\n },\n \"type\": \"emails\"\n }\n}" + } + ], + "step": "there is a valid \"oncall_email\" in the system", + "key": "oncall_email", + "tag": "On-Call", + "operationId": "CreateUserEmailNotificationChannel" + }, { "parameters": [ { diff --git a/features/v2/on-call.feature b/features/v2/on-call.feature index 39640938e4a1..ea48ab4dc6e9 100644 --- a/features/v2/on-call.feature +++ b/features/v2/on-call.feature @@ -43,6 +43,32 @@ Feature: On-Call When the request is sent Then the response status is 201 Created + @team:DataDog/on-call + Scenario: Create an On-Call email for a user returns "Bad Request" response + Given new "CreateUserEmailNotificationChannel" request + And there is a valid "user" in the system + And request contains "user_id" parameter from "user.data.id" + And body with value {"data": {"attributes": {"active": true, "address": "", "alias": "", "formats": ["html"]}, "type": "emails"}} + When the request is sent + Then the response status is 400 Bad Request + + @replay-only @team:DataDog/on-call + Scenario: Create an On-Call email for a user returns "Created" response + Given new "CreateUserEmailNotificationChannel" request + And there is a valid "user" in the system + And request contains "user_id" parameter from "user.data.id" + And body with value {"data": {"attributes": {"active": true, "address": "john.doe@datadoghq.com", "alias": "", "formats": ["html"]}, "type": "emails"}} + When the request is sent + Then the response status is 201 Created + + @team:DataDog/on-call + Scenario: Create an On-Call email for a user returns "Not Found" response + Given new "CreateUserEmailNotificationChannel" request + And request contains "user_id" parameter with value "00000000-0000-0000-0000-000000000000" + And body with value {"data": {"attributes": {"active": true, "address": "john.doe@datadoghq.com", "alias": "", "formats": ["html"]}, "type": "emails"}} + When the request is sent + Then the response status is 404 Not Found + @team:DataDog/on-call Scenario: Delete On-Call escalation policy returns "No Content" response Given new "DeleteOnCallEscalationPolicy" request @@ -77,6 +103,49 @@ Feature: On-Call When the request is sent Then the response status is 404 Not Found + @team:DataDog/on-call + Scenario: Delete an On-Call email for a missing email returns "Not Found" response + Given new "DeleteUserEmailNotificationChannel" request + And there is a valid "user" in the system + And request contains "user_id" parameter from "user.data.id" + And request contains "email_id" parameter with value "00000000-0000-0000-0000-000000000000" + When the request is sent + Then the response status is 404 Not Found + + @team:DataDog/on-call + Scenario: Delete an On-Call email for a missing user returns "Not Found" response + Given new "DeleteUserEmailNotificationChannel" request + And request contains "user_id" parameter with value "00000000-0000-0000-0000-000000000000" + And request contains "email_id" parameter with value "00000000-0000-0000-0000-000000000000" + When the request is sent + Then the response status is 404 Not Found + + @generated @skip @team:DataDog/on-call + Scenario: Delete an On-Call email for a user returns "Bad Request" response + Given new "DeleteUserEmailNotificationChannel" request + And request contains "user_id" parameter from "REPLACE.ME" + And request contains "email_id" parameter from "REPLACE.ME" + When the request is sent + Then the response status is 400 Bad Request + + @replay-only @team:DataDog/on-call + Scenario: Delete an On-Call email for a user returns "No Content" response + Given new "DeleteUserEmailNotificationChannel" request + And there is a valid "user" in the system + And there is a valid "oncall_email" in the system + And request contains "user_id" parameter from "user.data.id" + And request contains "email_id" parameter from "oncall_email.data.id" + When the request is sent + Then the response status is 204 No Content + + @generated @skip @team:DataDog/on-call + Scenario: Delete an On-Call email for a user returns "Not Found" response + Given new "DeleteUserEmailNotificationChannel" request + And request contains "user_id" parameter from "REPLACE.ME" + And request contains "email_id" parameter from "REPLACE.ME" + When the request is sent + Then the response status is 404 Not Found + @generated @skip @team:DataDog/on-call Scenario: Get On-Call escalation policy returns "Bad Request" response Given new "GetOnCallEscalationPolicy" request @@ -126,6 +195,32 @@ Feature: On-Call When the request is sent Then the response status is 200 OK + @generated @skip @team:DataDog/on-call + Scenario: Get an On-Call email for a user returns "Bad Request" response + Given new "GetUserEmailNotificationChannel" request + And request contains "user_id" parameter from "REPLACE.ME" + And request contains "email_id" parameter from "REPLACE.ME" + When the request is sent + Then the response status is 400 Bad Request + + @generated @skip @team:DataDog/on-call + Scenario: Get an On-Call email for a user returns "Not Found" response + Given new "GetUserEmailNotificationChannel" request + And request contains "user_id" parameter from "REPLACE.ME" + And request contains "email_id" parameter from "REPLACE.ME" + When the request is sent + Then the response status is 404 Not Found + + @replay-only @team:DataDog/on-call + Scenario: Get an On-Call email for a user returns "OK" response + Given new "GetUserEmailNotificationChannel" request + And there is a valid "user" in the system + And there is a valid "oncall_email" in the system + And request contains "user_id" parameter from "user.data.id" + And request contains "email_id" parameter from "oncall_email.data.id" + When the request is sent + Then the response status is 200 OK + @generated @skip @team:DataDog/on-call Scenario: Get team on-call users returns "Bad Request" response Given new "GetTeamOnCallUsers" request @@ -243,3 +338,32 @@ Feature: On-Call And body with value {"data": { "id": "{{ schedule.data.id }}", "attributes": {"layers": [{"id": "{{ schedule.data.relationships.layers.data[0].id }}" , "effective_date": "{{ timeISO('now - 10d') }}", "end_date": "{{ timeISO('now + 10d') }}", "interval": {"seconds": 3600}, "members": [{"user": {"id": "{{user.data.id}}"}}], "name": "Layer 1", "restrictions": [{"end_day": "friday", "end_time": "17:00:00", "start_day": "monday", "start_time": "09:00:00"}], "rotation_start": "{{ timeISO('now - 5d') }}"}], "name": "{{ unique }}", "time_zone": "America/New_York"}, "relationships": {"teams": {"data": [{"id": "{{dd_team.data.id}}", "type": "teams"}]}}, "type": "schedules"}} When the request is sent Then the response status is 200 OK + + @generated @skip @team:DataDog/on-call + Scenario: Update an On-Call email for a user returns "Bad Request" response + Given new "UpdateUserEmailNotificationChannel" request + And request contains "user_id" parameter from "REPLACE.ME" + And request contains "email_id" parameter from "REPLACE.ME" + And body with value {"data": {"attributes": {"active": true, "address": "john.doe@datadoghq.com", "alias": "", "formats": ["html"]}, "type": "emails"}} + When the request is sent + Then the response status is 400 Bad Request + + @generated @skip @team:DataDog/on-call + Scenario: Update an On-Call email for a user returns "Not Found" response + Given new "UpdateUserEmailNotificationChannel" request + And request contains "user_id" parameter from "REPLACE.ME" + And request contains "email_id" parameter from "REPLACE.ME" + And body with value {"data": {"attributes": {"active": true, "address": "john.doe@datadoghq.com", "alias": "", "formats": ["html"]}, "type": "emails"}} + When the request is sent + Then the response status is 404 Not Found + + @replay-only @team:DataDog/on-call + Scenario: Update an On-Call email for a user returns "OK" response + Given new "UpdateUserEmailNotificationChannel" request + And there is a valid "user" in the system + And there is a valid "oncall_email" in the system + And request contains "user_id" parameter from "user.data.id" + And request contains "email_id" parameter from "oncall_email.data.id" + And body with value {"data": {"id": "{{oncall_email.data.id}}", "attributes": {"active": true, "address": "{{oncall_email.data.attributes.address}}", "alias": "{{ unique }}-alias", "formats": ["html"]}, "type": "emails"}} + When the request is sent + Then the response status is 200 OK diff --git a/features/v2/undo.json b/features/v2/undo.json index cd8c18bf0780..93dc5840b656 100644 --- a/features/v2/undo.json +++ b/features/v2/undo.json @@ -2766,6 +2766,30 @@ "type": "idempotent" } }, + "CreateUserEmailNotificationChannel": { + "tag": "On-Call", + "undo": { + "type": "safe" + } + }, + "DeleteUserEmailNotificationChannel": { + "tag": "On-Call", + "undo": { + "type": "safe" + } + }, + "GetUserEmailNotificationChannel": { + "tag": "On-Call", + "undo": { + "type": "safe" + } + }, + "UpdateUserEmailNotificationChannel": { + "tag": "On-Call", + "undo": { + "type": "safe" + } + }, "ListOrgConfigs": { "tag": "Organizations", "undo": { diff --git a/private/bdd_runner/src/support/scenarios_model_mapping.ts b/private/bdd_runner/src/support/scenarios_model_mapping.ts index c9aae4e5b427..fca92aa6b563 100644 --- a/private/bdd_runner/src/support/scenarios_model_mapping.ts +++ b/private/bdd_runner/src/support/scenarios_model_mapping.ts @@ -7253,6 +7253,54 @@ export const ScenariosModelMappings: { [key: string]: OperationMapping } = { }, operationResponseType: "TeamRoutingRules", }, + "OnCallApi.V2.CreateUserEmailNotificationChannel": { + userId: { + type: "string", + format: "", + }, + body: { + type: "EmailCreateRequest", + format: "", + }, + operationResponseType: "Email", + }, + "OnCallApi.V2.GetUserEmailNotificationChannel": { + userId: { + type: "string", + format: "", + }, + emailId: { + type: "string", + format: "", + }, + operationResponseType: "Email", + }, + "OnCallApi.V2.UpdateUserEmailNotificationChannel": { + userId: { + type: "string", + format: "", + }, + emailId: { + type: "string", + format: "", + }, + body: { + type: "EmailUpdateRequest", + format: "", + }, + operationResponseType: "Email", + }, + "OnCallApi.V2.DeleteUserEmailNotificationChannel": { + userId: { + type: "string", + format: "", + }, + emailId: { + type: "string", + format: "", + }, + operationResponseType: "{}", + }, "OnCallPagingApi.V2.CreateOnCallPage": { body: { type: "CreatePageRequest", diff --git a/services/error_tracking/src/v2/ErrorTrackingApi.ts b/services/error_tracking/src/v2/ErrorTrackingApi.ts index 1b004f213a54..55e36055c5d6 100644 --- a/services/error_tracking/src/v2/ErrorTrackingApi.ts +++ b/services/error_tracking/src/v2/ErrorTrackingApi.ts @@ -647,7 +647,7 @@ export interface ErrorTrackingApiGetIssueRequest { */ issueId: string; /** - * Comma-separated list of relationship objects that should be included in the response. Possible values are `assignee`, `case`, and `team_owners`. + * Comma-separated list of relationship objects that should be included in the response. * @type Array */ include?: Array; @@ -660,7 +660,7 @@ export interface ErrorTrackingApiSearchIssuesRequest { */ body: IssuesSearchRequest; /** - * Comma-separated list of relationship objects that should be included in the response. Possible values are `issue`, `issue.assignee`, `issue.case`, and `issue.team_owners`. + * Comma-separated list of relationship objects that should be included in the response. * @type Array */ include?: Array; diff --git a/services/on_call/src/v2/OnCallApi.ts b/services/on_call/src/v2/OnCallApi.ts index e1e36ff7b598..cc666e61dc94 100644 --- a/services/on_call/src/v2/OnCallApi.ts +++ b/services/on_call/src/v2/OnCallApi.ts @@ -23,6 +23,9 @@ import { import { TypingInfo } from "./models/TypingInfo"; import { APIErrorResponse } from "./models/APIErrorResponse"; +import { Email } from "./models/Email"; +import { EmailCreateRequest } from "./models/EmailCreateRequest"; +import { EmailUpdateRequest } from "./models/EmailUpdateRequest"; import { EscalationPolicy } from "./models/EscalationPolicy"; import { EscalationPolicyCreateRequest } from "./models/EscalationPolicyCreateRequest"; import { EscalationPolicyUpdateRequest } from "./models/EscalationPolicyUpdateRequest"; @@ -166,6 +169,67 @@ export class OnCallApiRequestFactory extends BaseAPIRequestFactory { return requestContext; } + public async createUserEmailNotificationChannel( + userId: string, + body: EmailCreateRequest, + _options?: Configuration, + ): Promise { + const _config = _options || this.configuration; + + // verify required parameter 'userId' is not null or undefined + if (userId === null || userId === undefined) { + throw new RequiredError("userId", "createUserEmailNotificationChannel"); + } + + // verify required parameter 'body' is not null or undefined + if (body === null || body === undefined) { + throw new RequiredError("body", "createUserEmailNotificationChannel"); + } + + // Path Params + const localVarPath = + "/api/v2/on-call/users/{user_id}/notification-channels/emails".replace( + "{user_id}", + encodeURIComponent(String(userId)), + ); + + // Make Request Context + const { server, overrides } = _config.getServerAndOverrides( + "OnCallApi.v2.createUserEmailNotificationChannel", + OnCallApi.operationServers, + ); + const requestContext = server.makeRequestContext( + localVarPath, + HttpMethod.POST, + overrides, + ); + requestContext.setHeaderParam("Accept", "application/json"); + requestContext.setHttpConfig(_config.httpConfig); + + // Set User-Agent + if (this.userAgent) { + requestContext.setHeaderParam("User-Agent", this.userAgent); + } + + // Body Params + const contentType = getPreferredMediaType(["application/json"]); + requestContext.setHeaderParam("Content-Type", contentType); + const serializedBody = stringify( + serialize(body, TypingInfo, "EmailCreateRequest", ""), + contentType, + ); + requestContext.setBody(serializedBody); + + // Apply auth methods + applySecurityAuthentication(_config, requestContext, [ + "apiKeyAuth", + "appKeyAuth", + "AuthZ", + ]); + + return requestContext; + } + public async deleteOnCallEscalationPolicy( policyId: string, _options?: Configuration, @@ -257,6 +321,57 @@ export class OnCallApiRequestFactory extends BaseAPIRequestFactory { return requestContext; } + public async deleteUserEmailNotificationChannel( + userId: string, + emailId: string, + _options?: Configuration, + ): Promise { + const _config = _options || this.configuration; + + // verify required parameter 'userId' is not null or undefined + if (userId === null || userId === undefined) { + throw new RequiredError("userId", "deleteUserEmailNotificationChannel"); + } + + // verify required parameter 'emailId' is not null or undefined + if (emailId === null || emailId === undefined) { + throw new RequiredError("emailId", "deleteUserEmailNotificationChannel"); + } + + // Path Params + const localVarPath = + "/api/v2/on-call/users/{user_id}/notification-channels/emails/{email_id}" + .replace("{user_id}", encodeURIComponent(String(userId))) + .replace("{email_id}", encodeURIComponent(String(emailId))); + + // Make Request Context + const { server, overrides } = _config.getServerAndOverrides( + "OnCallApi.v2.deleteUserEmailNotificationChannel", + OnCallApi.operationServers, + ); + const requestContext = server.makeRequestContext( + localVarPath, + HttpMethod.DELETE, + overrides, + ); + requestContext.setHeaderParam("Accept", "*/*"); + requestContext.setHttpConfig(_config.httpConfig); + + // Set User-Agent + if (this.userAgent) { + requestContext.setHeaderParam("User-Agent", this.userAgent); + } + + // Apply auth methods + applySecurityAuthentication(_config, requestContext, [ + "apiKeyAuth", + "appKeyAuth", + "AuthZ", + ]); + + return requestContext; + } + public async getOnCallEscalationPolicy( policyId: string, include?: string, @@ -543,6 +658,57 @@ export class OnCallApiRequestFactory extends BaseAPIRequestFactory { return requestContext; } + public async getUserEmailNotificationChannel( + userId: string, + emailId: string, + _options?: Configuration, + ): Promise { + const _config = _options || this.configuration; + + // verify required parameter 'userId' is not null or undefined + if (userId === null || userId === undefined) { + throw new RequiredError("userId", "getUserEmailNotificationChannel"); + } + + // verify required parameter 'emailId' is not null or undefined + if (emailId === null || emailId === undefined) { + throw new RequiredError("emailId", "getUserEmailNotificationChannel"); + } + + // Path Params + const localVarPath = + "/api/v2/on-call/users/{user_id}/notification-channels/emails/{email_id}" + .replace("{user_id}", encodeURIComponent(String(userId))) + .replace("{email_id}", encodeURIComponent(String(emailId))); + + // Make Request Context + const { server, overrides } = _config.getServerAndOverrides( + "OnCallApi.v2.getUserEmailNotificationChannel", + OnCallApi.operationServers, + ); + const requestContext = server.makeRequestContext( + localVarPath, + HttpMethod.GET, + overrides, + ); + requestContext.setHeaderParam("Accept", "application/json"); + requestContext.setHttpConfig(_config.httpConfig); + + // Set User-Agent + if (this.userAgent) { + requestContext.setHeaderParam("User-Agent", this.userAgent); + } + + // Apply auth methods + applySecurityAuthentication(_config, requestContext, [ + "apiKeyAuth", + "appKeyAuth", + "AuthZ", + ]); + + return requestContext; + } + public async setOnCallTeamRoutingRules( teamId: string, body: TeamRoutingRulesRequest, @@ -754,6 +920,72 @@ export class OnCallApiRequestFactory extends BaseAPIRequestFactory { return requestContext; } + + public async updateUserEmailNotificationChannel( + userId: string, + emailId: string, + body: EmailUpdateRequest, + _options?: Configuration, + ): Promise { + const _config = _options || this.configuration; + + // verify required parameter 'userId' is not null or undefined + if (userId === null || userId === undefined) { + throw new RequiredError("userId", "updateUserEmailNotificationChannel"); + } + + // verify required parameter 'emailId' is not null or undefined + if (emailId === null || emailId === undefined) { + throw new RequiredError("emailId", "updateUserEmailNotificationChannel"); + } + + // verify required parameter 'body' is not null or undefined + if (body === null || body === undefined) { + throw new RequiredError("body", "updateUserEmailNotificationChannel"); + } + + // Path Params + const localVarPath = + "/api/v2/on-call/users/{user_id}/notification-channels/emails/{email_id}" + .replace("{user_id}", encodeURIComponent(String(userId))) + .replace("{email_id}", encodeURIComponent(String(emailId))); + + // Make Request Context + const { server, overrides } = _config.getServerAndOverrides( + "OnCallApi.v2.updateUserEmailNotificationChannel", + OnCallApi.operationServers, + ); + const requestContext = server.makeRequestContext( + localVarPath, + HttpMethod.PUT, + overrides, + ); + requestContext.setHeaderParam("Accept", "application/json"); + requestContext.setHttpConfig(_config.httpConfig); + + // Set User-Agent + if (this.userAgent) { + requestContext.setHeaderParam("User-Agent", this.userAgent); + } + + // Body Params + const contentType = getPreferredMediaType(["application/json"]); + requestContext.setHeaderParam("Content-Type", contentType); + const serializedBody = stringify( + serialize(body, TypingInfo, "EmailUpdateRequest", ""), + contentType, + ); + requestContext.setBody(serializedBody); + + // Apply auth methods + applySecurityAuthentication(_config, requestContext, [ + "apiKeyAuth", + "appKeyAuth", + "AuthZ", + ]); + + return requestContext; + } } export class OnCallApiResponseProcessor { @@ -879,6 +1111,68 @@ export class OnCallApiResponseProcessor { ); } + /** + * Unwraps the actual response sent by the server from the response context and deserializes the response content + * to the expected objects + * + * @params response Response returned by the server for a request to createUserEmailNotificationChannel + * @throws ApiException if the response code was not in [200, 299] + */ + public async createUserEmailNotificationChannel( + response: ResponseContext, + ): Promise { + const contentType = normalizeMediaType(response.headers["content-type"]); + if (response.httpStatusCode === 201) { + const body: Email = deserialize( + parse(await response.body.text(), contentType), + TypingInfo, + "Email", + ) as Email; + return body; + } + if ( + response.httpStatusCode === 400 || + response.httpStatusCode === 401 || + response.httpStatusCode === 403 || + response.httpStatusCode === 404 || + response.httpStatusCode === 429 + ) { + const bodyText = parse(await response.body.text(), contentType); + let body: APIErrorResponse; + try { + body = deserialize( + bodyText, + TypingInfo, + "APIErrorResponse", + ) as APIErrorResponse; + } catch (error) { + logger.debug(`Got error deserializing error: ${error}`); + throw new ApiException( + response.httpStatusCode, + bodyText, + ); + } + throw new ApiException(response.httpStatusCode, body); + } + + // Work around for missing responses in specification, e.g. for petstore.yaml + if (response.httpStatusCode >= 200 && response.httpStatusCode <= 299) { + const body: Email = deserialize( + parse(await response.body.text(), contentType), + TypingInfo, + "Email", + "", + ) as Email; + return body; + } + + const body = (await response.body.text()) || ""; + throw new ApiException( + response.httpStatusCode, + 'Unknown API Status Code!\nBody: "' + body + '"', + ); + } + /** * Unwraps the actual response sent by the server from the response context and deserializes the response content * to the expected objects @@ -977,6 +1271,57 @@ export class OnCallApiResponseProcessor { ); } + /** + * Unwraps the actual response sent by the server from the response context and deserializes the response content + * to the expected objects + * + * @params response Response returned by the server for a request to deleteUserEmailNotificationChannel + * @throws ApiException if the response code was not in [200, 299] + */ + public async deleteUserEmailNotificationChannel( + response: ResponseContext, + ): Promise { + const contentType = normalizeMediaType(response.headers["content-type"]); + if (response.httpStatusCode === 204) { + return; + } + if ( + response.httpStatusCode === 400 || + response.httpStatusCode === 401 || + response.httpStatusCode === 403 || + response.httpStatusCode === 404 || + response.httpStatusCode === 429 + ) { + const bodyText = parse(await response.body.text(), contentType); + let body: APIErrorResponse; + try { + body = deserialize( + bodyText, + TypingInfo, + "APIErrorResponse", + ) as APIErrorResponse; + } catch (error) { + logger.debug(`Got error deserializing error: ${error}`); + throw new ApiException( + response.httpStatusCode, + bodyText, + ); + } + throw new ApiException(response.httpStatusCode, body); + } + + // Work around for missing responses in specification, e.g. for petstore.yaml + if (response.httpStatusCode >= 200 && response.httpStatusCode <= 299) { + return; + } + + const body = (await response.body.text()) || ""; + throw new ApiException( + response.httpStatusCode, + 'Unknown API Status Code!\nBody: "' + body + '"', + ); + } + /** * Unwraps the actual response sent by the server from the response context and deserializes the response content * to the expected objects @@ -1278,6 +1623,68 @@ export class OnCallApiResponseProcessor { ); } + /** + * Unwraps the actual response sent by the server from the response context and deserializes the response content + * to the expected objects + * + * @params response Response returned by the server for a request to getUserEmailNotificationChannel + * @throws ApiException if the response code was not in [200, 299] + */ + public async getUserEmailNotificationChannel( + response: ResponseContext, + ): Promise { + const contentType = normalizeMediaType(response.headers["content-type"]); + if (response.httpStatusCode === 200) { + const body: Email = deserialize( + parse(await response.body.text(), contentType), + TypingInfo, + "Email", + ) as Email; + return body; + } + if ( + response.httpStatusCode === 400 || + response.httpStatusCode === 401 || + response.httpStatusCode === 403 || + response.httpStatusCode === 404 || + response.httpStatusCode === 429 + ) { + const bodyText = parse(await response.body.text(), contentType); + let body: APIErrorResponse; + try { + body = deserialize( + bodyText, + TypingInfo, + "APIErrorResponse", + ) as APIErrorResponse; + } catch (error) { + logger.debug(`Got error deserializing error: ${error}`); + throw new ApiException( + response.httpStatusCode, + bodyText, + ); + } + throw new ApiException(response.httpStatusCode, body); + } + + // Work around for missing responses in specification, e.g. for petstore.yaml + if (response.httpStatusCode >= 200 && response.httpStatusCode <= 299) { + const body: Email = deserialize( + parse(await response.body.text(), contentType), + TypingInfo, + "Email", + "", + ) as Email; + return body; + } + + const body = (await response.body.text()) || ""; + throw new ApiException( + response.httpStatusCode, + 'Unknown API Status Code!\nBody: "' + body + '"', + ); + } + /** * Unwraps the actual response sent by the server from the response context and deserializes the response content * to the expected objects @@ -1457,6 +1864,68 @@ export class OnCallApiResponseProcessor { 'Unknown API Status Code!\nBody: "' + body + '"', ); } + + /** + * Unwraps the actual response sent by the server from the response context and deserializes the response content + * to the expected objects + * + * @params response Response returned by the server for a request to updateUserEmailNotificationChannel + * @throws ApiException if the response code was not in [200, 299] + */ + public async updateUserEmailNotificationChannel( + response: ResponseContext, + ): Promise { + const contentType = normalizeMediaType(response.headers["content-type"]); + if (response.httpStatusCode === 200) { + const body: Email = deserialize( + parse(await response.body.text(), contentType), + TypingInfo, + "Email", + ) as Email; + return body; + } + if ( + response.httpStatusCode === 400 || + response.httpStatusCode === 401 || + response.httpStatusCode === 403 || + response.httpStatusCode === 404 || + response.httpStatusCode === 429 + ) { + const bodyText = parse(await response.body.text(), contentType); + let body: APIErrorResponse; + try { + body = deserialize( + bodyText, + TypingInfo, + "APIErrorResponse", + ) as APIErrorResponse; + } catch (error) { + logger.debug(`Got error deserializing error: ${error}`); + throw new ApiException( + response.httpStatusCode, + bodyText, + ); + } + throw new ApiException(response.httpStatusCode, body); + } + + // Work around for missing responses in specification, e.g. for petstore.yaml + if (response.httpStatusCode >= 200 && response.httpStatusCode <= 299) { + const body: Email = deserialize( + parse(await response.body.text(), contentType), + TypingInfo, + "Email", + "", + ) as Email; + return body; + } + + const body = (await response.body.text()) || ""; + throw new ApiException( + response.httpStatusCode, + 'Unknown API Status Code!\nBody: "' + body + '"', + ); + } } export interface OnCallApiCreateOnCallEscalationPolicyRequest { @@ -1483,6 +1952,18 @@ export interface OnCallApiCreateOnCallScheduleRequest { include?: string; } +export interface OnCallApiCreateUserEmailNotificationChannelRequest { + /** + * The user ID + * @type string + */ + userId: string; + /** + * @type EmailCreateRequest + */ + body: EmailCreateRequest; +} + export interface OnCallApiDeleteOnCallEscalationPolicyRequest { /** * The ID of the escalation policy @@ -1499,6 +1980,19 @@ export interface OnCallApiDeleteOnCallScheduleRequest { scheduleId: string; } +export interface OnCallApiDeleteUserEmailNotificationChannelRequest { + /** + * The user ID + * @type string + */ + userId: string; + /** + * The email ID + * @type string + */ + emailId: string; +} + export interface OnCallApiGetOnCallEscalationPolicyRequest { /** * The ID of the escalation policy @@ -1569,6 +2063,19 @@ export interface OnCallApiGetTeamOnCallUsersRequest { include?: string; } +export interface OnCallApiGetUserEmailNotificationChannelRequest { + /** + * The user ID + * @type string + */ + userId: string; + /** + * The email ID + * @type string + */ + emailId: string; +} + export interface OnCallApiSetOnCallTeamRoutingRulesRequest { /** * The team ID @@ -1620,6 +2127,23 @@ export interface OnCallApiUpdateOnCallScheduleRequest { include?: string; } +export interface OnCallApiUpdateUserEmailNotificationChannelRequest { + /** + * The user ID + * @type string + */ + userId: string; + /** + * The email ID + * @type string + */ + emailId: string; + /** + * @type EmailUpdateRequest + */ + body: EmailUpdateRequest; +} + export class OnCallApi { private requestFactory: OnCallApiRequestFactory; private responseProcessor: OnCallApiResponseProcessor; @@ -1686,6 +2210,31 @@ export class OnCallApi { }); } + /** + * Create a new email notification channel for an on-call user + * @param param The request object + */ + public createUserEmailNotificationChannel( + param: OnCallApiCreateUserEmailNotificationChannelRequest, + options?: Configuration, + ): Promise { + const requestContextPromise = + this.requestFactory.createUserEmailNotificationChannel( + param.userId, + param.body, + options, + ); + return requestContextPromise.then((requestContext) => { + return this.configuration.httpApi + .send(requestContext) + .then((responseContext) => { + return this.responseProcessor.createUserEmailNotificationChannel( + responseContext, + ); + }); + }); + } + /** * Delete an On-Call escalation policy * @param param The request object @@ -1728,6 +2277,31 @@ export class OnCallApi { }); } + /** + * Delete an email notification channel for an on-call user + * @param param The request object + */ + public deleteUserEmailNotificationChannel( + param: OnCallApiDeleteUserEmailNotificationChannelRequest, + options?: Configuration, + ): Promise { + const requestContextPromise = + this.requestFactory.deleteUserEmailNotificationChannel( + param.userId, + param.emailId, + options, + ); + return requestContextPromise.then((requestContext) => { + return this.configuration.httpApi + .send(requestContext) + .then((responseContext) => { + return this.responseProcessor.deleteUserEmailNotificationChannel( + responseContext, + ); + }); + }); + } + /** * Get an On-Call escalation policy * @param param The request object @@ -1843,6 +2417,31 @@ export class OnCallApi { }); } + /** + * Get an email notification channel for an on-call user + * @param param The request object + */ + public getUserEmailNotificationChannel( + param: OnCallApiGetUserEmailNotificationChannelRequest, + options?: Configuration, + ): Promise { + const requestContextPromise = + this.requestFactory.getUserEmailNotificationChannel( + param.userId, + param.emailId, + options, + ); + return requestContextPromise.then((requestContext) => { + return this.configuration.httpApi + .send(requestContext) + .then((responseContext) => { + return this.responseProcessor.getUserEmailNotificationChannel( + responseContext, + ); + }); + }); + } + /** * Set a team's On-Call routing rules * @param param The request object @@ -1916,4 +2515,30 @@ export class OnCallApi { }); }); } + + /** + * Update an email notification channel for an on-call user + * @param param The request object + */ + public updateUserEmailNotificationChannel( + param: OnCallApiUpdateUserEmailNotificationChannelRequest, + options?: Configuration, + ): Promise { + const requestContextPromise = + this.requestFactory.updateUserEmailNotificationChannel( + param.userId, + param.emailId, + param.body, + options, + ); + return requestContextPromise.then((requestContext) => { + return this.configuration.httpApi + .send(requestContext) + .then((responseContext) => { + return this.responseProcessor.updateUserEmailNotificationChannel( + responseContext, + ); + }); + }); + } } diff --git a/services/on_call/src/v2/index.ts b/services/on_call/src/v2/index.ts index bc52840bd0d0..d61a18458624 100644 --- a/services/on_call/src/v2/index.ts +++ b/services/on_call/src/v2/index.ts @@ -1,16 +1,20 @@ export { OnCallApiCreateOnCallEscalationPolicyRequest, OnCallApiCreateOnCallScheduleRequest, + OnCallApiCreateUserEmailNotificationChannelRequest, OnCallApiDeleteOnCallEscalationPolicyRequest, OnCallApiDeleteOnCallScheduleRequest, + OnCallApiDeleteUserEmailNotificationChannelRequest, OnCallApiGetOnCallEscalationPolicyRequest, OnCallApiGetOnCallScheduleRequest, OnCallApiGetOnCallTeamRoutingRulesRequest, OnCallApiGetScheduleOnCallUserRequest, OnCallApiGetTeamOnCallUsersRequest, + OnCallApiGetUserEmailNotificationChannelRequest, OnCallApiSetOnCallTeamRoutingRulesRequest, OnCallApiUpdateOnCallEscalationPolicyRequest, OnCallApiUpdateOnCallScheduleRequest, + OnCallApiUpdateUserEmailNotificationChannelRequest, OnCallApi, } from "./OnCallApi"; @@ -18,6 +22,13 @@ export { APIErrorResponse } from "./models/APIErrorResponse"; export { DataRelationshipsTeams } from "./models/DataRelationshipsTeams"; export { DataRelationshipsTeamsDataItems } from "./models/DataRelationshipsTeamsDataItems"; export { DataRelationshipsTeamsDataItemsType } from "./models/DataRelationshipsTeamsDataItemsType"; +export { Email } from "./models/Email"; +export { EmailAttributes } from "./models/EmailAttributes"; +export { EmailCreateRequest } from "./models/EmailCreateRequest"; +export { EmailData } from "./models/EmailData"; +export { EmailFormatType } from "./models/EmailFormatType"; +export { EmailType } from "./models/EmailType"; +export { EmailUpdateRequest } from "./models/EmailUpdateRequest"; export { Escalation } from "./models/Escalation"; export { EscalationPolicy } from "./models/EscalationPolicy"; export { EscalationPolicyCreateRequest } from "./models/EscalationPolicyCreateRequest"; diff --git a/services/on_call/src/v2/models/Email.ts b/services/on_call/src/v2/models/Email.ts new file mode 100644 index 000000000000..d5cac17149ea --- /dev/null +++ b/services/on_call/src/v2/models/Email.ts @@ -0,0 +1,46 @@ +import { AttributeTypeMap } from "@datadog/datadog-api-client"; + +import { EmailData } from "./EmailData"; + +/** + * On-Call User Email. + */ +export class Email { + /** + * Data for an on-call email resource. + */ + "data"?: EmailData; + /** + * A container for additional, undeclared properties. + * This is a holder for any undeclared properties as specified with + * the 'additionalProperties' keyword in the OAS document. + */ + "additionalProperties"?: { [key: string]: any }; + /** + * @ignore + */ + "_unparsed"?: boolean; + + /** + * @ignore + */ + static readonly attributeTypeMap: AttributeTypeMap = { + data: { + baseName: "data", + type: "EmailData", + }, + additionalProperties: { + baseName: "additionalProperties", + type: "{ [key: string]: any; }", + }, + }; + + /** + * @ignore + */ + static getAttributeTypeMap(): AttributeTypeMap { + return Email.attributeTypeMap; + } + + public constructor() {} +} diff --git a/services/on_call/src/v2/models/EmailAttributes.ts b/services/on_call/src/v2/models/EmailAttributes.ts new file mode 100644 index 000000000000..90986b00d5d2 --- /dev/null +++ b/services/on_call/src/v2/models/EmailAttributes.ts @@ -0,0 +1,70 @@ +import { AttributeTypeMap } from "@datadog/datadog-api-client"; + +import { EmailFormatType } from "./EmailFormatType"; + +/** + * Attributes for an on-call email. + */ +export class EmailAttributes { + /** + * Whether the email is currently active. + */ + "active"?: boolean; + /** + * Email address. + */ + "address"?: string; + /** + * Optional display alias for the email. + */ + "alias"?: string; + /** + * Preferred content formats for notifications. + */ + "formats"?: Array; + /** + * A container for additional, undeclared properties. + * This is a holder for any undeclared properties as specified with + * the 'additionalProperties' keyword in the OAS document. + */ + "additionalProperties"?: { [key: string]: any }; + /** + * @ignore + */ + "_unparsed"?: boolean; + + /** + * @ignore + */ + static readonly attributeTypeMap: AttributeTypeMap = { + active: { + baseName: "active", + type: "boolean", + }, + address: { + baseName: "address", + type: "string", + }, + alias: { + baseName: "alias", + type: "string", + }, + formats: { + baseName: "formats", + type: "Array", + }, + additionalProperties: { + baseName: "additionalProperties", + type: "{ [key: string]: any; }", + }, + }; + + /** + * @ignore + */ + static getAttributeTypeMap(): AttributeTypeMap { + return EmailAttributes.attributeTypeMap; + } + + public constructor() {} +} diff --git a/services/on_call/src/v2/models/EmailCreateRequest.ts b/services/on_call/src/v2/models/EmailCreateRequest.ts new file mode 100644 index 000000000000..be844bf61058 --- /dev/null +++ b/services/on_call/src/v2/models/EmailCreateRequest.ts @@ -0,0 +1,46 @@ +import { AttributeTypeMap } from "@datadog/datadog-api-client"; + +import { EmailData } from "./EmailData"; + +/** + * Request body for creating an On-Call email notification channel. + */ +export class EmailCreateRequest { + /** + * Data for an on-call email resource. + */ + "data"?: EmailData; + /** + * A container for additional, undeclared properties. + * This is a holder for any undeclared properties as specified with + * the 'additionalProperties' keyword in the OAS document. + */ + "additionalProperties"?: { [key: string]: any }; + /** + * @ignore + */ + "_unparsed"?: boolean; + + /** + * @ignore + */ + static readonly attributeTypeMap: AttributeTypeMap = { + data: { + baseName: "data", + type: "EmailData", + }, + additionalProperties: { + baseName: "additionalProperties", + type: "{ [key: string]: any; }", + }, + }; + + /** + * @ignore + */ + static getAttributeTypeMap(): AttributeTypeMap { + return EmailCreateRequest.attributeTypeMap; + } + + public constructor() {} +} diff --git a/services/on_call/src/v2/models/EmailData.ts b/services/on_call/src/v2/models/EmailData.ts new file mode 100644 index 000000000000..92804695a8e3 --- /dev/null +++ b/services/on_call/src/v2/models/EmailData.ts @@ -0,0 +1,64 @@ +import { AttributeTypeMap } from "@datadog/datadog-api-client"; + +import { EmailAttributes } from "./EmailAttributes"; +import { EmailType } from "./EmailType"; + +/** + * Data for an on-call email resource. + */ +export class EmailData { + /** + * Attributes for an on-call email. + */ + "attributes"?: EmailAttributes; + /** + * The email's unique identifier. + */ + "id"?: string; + /** + * Indicates that the resource is of type 'emails'. + */ + "type": EmailType; + /** + * A container for additional, undeclared properties. + * This is a holder for any undeclared properties as specified with + * the 'additionalProperties' keyword in the OAS document. + */ + "additionalProperties"?: { [key: string]: any }; + /** + * @ignore + */ + "_unparsed"?: boolean; + + /** + * @ignore + */ + static readonly attributeTypeMap: AttributeTypeMap = { + attributes: { + baseName: "attributes", + type: "EmailAttributes", + }, + id: { + baseName: "id", + type: "string", + }, + type: { + baseName: "type", + type: "EmailType", + required: true, + }, + additionalProperties: { + baseName: "additionalProperties", + type: "{ [key: string]: any; }", + }, + }; + + /** + * @ignore + */ + static getAttributeTypeMap(): AttributeTypeMap { + return EmailData.attributeTypeMap; + } + + public constructor() {} +} diff --git a/services/on_call/src/v2/models/EmailFormatType.ts b/services/on_call/src/v2/models/EmailFormatType.ts new file mode 100644 index 000000000000..5617da65de3e --- /dev/null +++ b/services/on_call/src/v2/models/EmailFormatType.ts @@ -0,0 +1,8 @@ +import { UnparsedObject } from "@datadog/datadog-api-client"; + +/** + * Specifies the format of the e-mail that is sent for On-Call notifications + */ +export type EmailFormatType = typeof HTML | typeof TEXT | UnparsedObject; +export const HTML = "html"; +export const TEXT = "text"; diff --git a/services/on_call/src/v2/models/EmailType.ts b/services/on_call/src/v2/models/EmailType.ts new file mode 100644 index 000000000000..02af359c0aeb --- /dev/null +++ b/services/on_call/src/v2/models/EmailType.ts @@ -0,0 +1,7 @@ +import { UnparsedObject } from "@datadog/datadog-api-client"; + +/** + * Indicates that the resource is of type 'emails'. + */ +export type EmailType = typeof EMAILS | UnparsedObject; +export const EMAILS = "emails"; diff --git a/services/on_call/src/v2/models/EmailUpdateRequest.ts b/services/on_call/src/v2/models/EmailUpdateRequest.ts new file mode 100644 index 000000000000..bf82e88413d0 --- /dev/null +++ b/services/on_call/src/v2/models/EmailUpdateRequest.ts @@ -0,0 +1,46 @@ +import { AttributeTypeMap } from "@datadog/datadog-api-client"; + +import { EmailData } from "./EmailData"; + +/** + * Request body for updating an On-Call email notification channel. + */ +export class EmailUpdateRequest { + /** + * Data for an on-call email resource. + */ + "data"?: EmailData; + /** + * A container for additional, undeclared properties. + * This is a holder for any undeclared properties as specified with + * the 'additionalProperties' keyword in the OAS document. + */ + "additionalProperties"?: { [key: string]: any }; + /** + * @ignore + */ + "_unparsed"?: boolean; + + /** + * @ignore + */ + static readonly attributeTypeMap: AttributeTypeMap = { + data: { + baseName: "data", + type: "EmailData", + }, + additionalProperties: { + baseName: "additionalProperties", + type: "{ [key: string]: any; }", + }, + }; + + /** + * @ignore + */ + static getAttributeTypeMap(): AttributeTypeMap { + return EmailUpdateRequest.attributeTypeMap; + } + + public constructor() {} +} diff --git a/services/on_call/src/v2/models/TypingInfo.ts b/services/on_call/src/v2/models/TypingInfo.ts index f2e6793b5ce1..07485185d63f 100644 --- a/services/on_call/src/v2/models/TypingInfo.ts +++ b/services/on_call/src/v2/models/TypingInfo.ts @@ -3,6 +3,11 @@ import { ModelTypingInfo } from "@datadog/datadog-api-client"; import { APIErrorResponse } from "./APIErrorResponse"; import { DataRelationshipsTeams } from "./DataRelationshipsTeams"; import { DataRelationshipsTeamsDataItems } from "./DataRelationshipsTeamsDataItems"; +import { Email } from "./Email"; +import { EmailAttributes } from "./EmailAttributes"; +import { EmailCreateRequest } from "./EmailCreateRequest"; +import { EmailData } from "./EmailData"; +import { EmailUpdateRequest } from "./EmailUpdateRequest"; import { Escalation } from "./Escalation"; import { EscalationPolicy } from "./EscalationPolicy"; import { EscalationPolicyCreateRequest } from "./EscalationPolicyCreateRequest"; @@ -110,6 +115,8 @@ import { UserTarget } from "./UserTarget"; export const TypingInfo: ModelTypingInfo = { enumsMap: { DataRelationshipsTeamsDataItemsType: ["teams"], + EmailFormatType: ["html", "text"], + EmailType: ["emails"], EscalationPolicyCreateRequestDataType: ["policies"], EscalationPolicyDataRelationshipsStepsDataItemsType: ["steps"], EscalationPolicyDataType: ["policies"], @@ -185,6 +192,11 @@ export const TypingInfo: ModelTypingInfo = { APIErrorResponse: APIErrorResponse, DataRelationshipsTeams: DataRelationshipsTeams, DataRelationshipsTeamsDataItems: DataRelationshipsTeamsDataItems, + Email: Email, + EmailAttributes: EmailAttributes, + EmailCreateRequest: EmailCreateRequest, + EmailData: EmailData, + EmailUpdateRequest: EmailUpdateRequest, Escalation: Escalation, EscalationPolicy: EscalationPolicy, EscalationPolicyCreateRequest: EscalationPolicyCreateRequest,