(null);
+
const fetchAll = async () => {
try {
- const [intRes, atRes, itgRes, s1Res] = await Promise.all([
+ const [intRes, atRes, itgRes, s1Res, mcRes] = await Promise.all([
fetch('/api/integrations/status'),
fetch('/api/sync/last-sync'),
fetch('/api/itglue/sync'),
fetch('/api/sentinelone/sync'),
+ fetch('/api/mimecast/status'),
]);
if (intRes.ok) setStatus(await intRes.json());
if (atRes.ok) {
@@ -69,6 +73,7 @@ export default function SyncOverviewPage() {
}
if (itgRes.ok) setItglueSyncData(await itgRes.json());
if (s1Res.ok) setS1SyncData(await s1Res.json());
+ if (mcRes.ok) setMimecastData(await mcRes.json());
} catch (e) {
console.error(e);
} finally {
@@ -147,6 +152,16 @@ export default function SyncOverviewPage() {
}
if (id === 'auvik') return { lastSync: status.auvik?.lastSync, configured: status.auvik?.configured };
if (id === 'addigy') return { lastSync: status.addigy?.lastSync, configured: status.addigy?.configured };
+ if (id === 'mimecast') {
+ if (!mimecastData) return null;
+ const s = mimecastData.stats ?? {};
+ return {
+ lastSync: s.lastSync ?? null,
+ connected: mimecastData.connected ?? false,
+ messages: s.messages ?? 0,
+ threats: s.threats ?? 0,
+ };
+ }
return null;
};
@@ -176,6 +191,11 @@ export default function SyncOverviewPage() {
if (summary.infected > 0) return ;
return ;
}
+ if (id === 'mimecast') {
+ if (!summary.connected) return ;
+ if ((summary as any).threats > 0) return ;
+ return ;
+ }
return ;
};
@@ -322,6 +342,24 @@ export default function SyncOverviewPage() {
)}
>
)}
+ {intg.id === 'mimecast' && summary && (
+ <>
+
+ Last sync
+ {fmtDate((summary as any).lastSync)}
+
+
+ Messages
+ {((summary as any).messages ?? 0).toLocaleString()}
+
+ {(summary as any).threats > 0 && (
+
+ Threat events
+ {(summary as any).threats}
+
+ )}
+ >
+ )}
{(intg.id === 'auvik' || intg.id === 'addigy') && (
Status
diff --git a/app/api/mimecast/messages/route.ts b/app/api/mimecast/messages/route.ts
new file mode 100644
index 0000000..f3c1162
--- /dev/null
+++ b/app/api/mimecast/messages/route.ts
@@ -0,0 +1,55 @@
+import { NextRequest, NextResponse } from 'next/server';
+import { postgresClient as pg } from '@/lib/services/postgres-client';
+
+export async function GET(req: NextRequest) {
+ try {
+ const { searchParams } = new URL(req.url);
+ const days = parseInt(searchParams.get('days') ?? '7');
+ const limit = Math.min(parseInt(searchParams.get('limit') ?? '200'), 1000);
+ const search = searchParams.get('search') ?? '';
+ const direction = searchParams.get('direction') ?? '';
+ const status = searchParams.get('status') ?? '';
+
+ const cutoff = new Date();
+ cutoff.setDate(cutoff.getDate() - days);
+
+ const conditions: string[] = ['sent_datetime >= $1'];
+ const params: any[] = [cutoff.toISOString()];
+ let paramIdx = 2;
+
+ if (direction) {
+ conditions.push(`direction = $${paramIdx++}`);
+ params.push(direction);
+ }
+ if (status) {
+ conditions.push(`status = $${paramIdx++}`);
+ params.push(status);
+ }
+ if (search) {
+ conditions.push(`(
+ sender_address ILIKE $${paramIdx} OR
+ recipient_address ILIKE $${paramIdx} OR
+ subject ILIKE $${paramIdx}
+ )`);
+ params.push(`%${search}%`);
+ paramIdx++;
+ }
+
+ const where = conditions.join(' AND ');
+ params.push(limit);
+
+ const result = await pg.query(`
+ SELECT id, sender_address, sender_domain, recipient_address, subject,
+ direction, status, action, spam_score, size_bytes, attachment_count,
+ sent_datetime, received_datetime, route, reject_reason, held_reason, source_ip
+ FROM mimecast_messages
+ WHERE ${where}
+ ORDER BY sent_datetime DESC
+ LIMIT $${paramIdx}
+ `, params);
+
+ return NextResponse.json({ messages: result.rows });
+ } catch (err: any) {
+ return NextResponse.json({ error: err.message }, { status: 500 });
+ }
+}
diff --git a/app/api/mimecast/status/route.ts b/app/api/mimecast/status/route.ts
new file mode 100644
index 0000000..6a4a949
--- /dev/null
+++ b/app/api/mimecast/status/route.ts
@@ -0,0 +1,29 @@
+import { NextResponse } from 'next/server';
+import { getMimecastClient } from '@/lib/services/mimecast-client';
+import { getMimecastStats } from '@/lib/services/mimecast-sync-service';
+
+export async function GET() {
+ try {
+ const client = getMimecastClient();
+ const [connection, stats] = await Promise.all([
+ client.testConnection(),
+ getMimecastStats().catch(() => null),
+ ]);
+
+ return NextResponse.json({
+ configured: true,
+ connected: connection.ok,
+ accountName: connection.accountName,
+ packageName: connection.packageName,
+ error: connection.error,
+ stats,
+ });
+ } catch (err: any) {
+ return NextResponse.json({
+ configured: false,
+ connected: false,
+ error: err.message,
+ stats: null,
+ });
+ }
+}
diff --git a/app/api/mimecast/threats/route.ts b/app/api/mimecast/threats/route.ts
new file mode 100644
index 0000000..451db83
--- /dev/null
+++ b/app/api/mimecast/threats/route.ts
@@ -0,0 +1,40 @@
+import { NextRequest, NextResponse } from 'next/server';
+import { postgresClient as pg } from '@/lib/services/postgres-client';
+
+export async function GET(req: NextRequest) {
+ try {
+ const { searchParams } = new URL(req.url);
+ const limit = Math.min(parseInt(searchParams.get('limit') ?? '200'), 1000);
+ const level = searchParams.get('level') ?? '';
+ const type = searchParams.get('type') ?? '';
+
+ const conditions: string[] = [];
+ const params: any[] = [];
+ let paramIdx = 1;
+
+ if (level) {
+ conditions.push(`threat_level = $${paramIdx++}`);
+ params.push(level);
+ }
+ if (type) {
+ conditions.push(`event_type = $${paramIdx++}`);
+ params.push(type);
+ }
+
+ const where = conditions.length ? `WHERE ${conditions.join(' AND ')}` : '';
+ params.push(limit);
+
+ const result = await pg.query(`
+ SELECT id, message_id, event_type, threat_level, url, file_name,
+ verdict, actor_email, event_datetime
+ FROM mimecast_threat_events
+ ${where}
+ ORDER BY event_datetime DESC NULLS LAST
+ LIMIT $${paramIdx}
+ `, params);
+
+ return NextResponse.json({ threats: result.rows });
+ } catch (err: any) {
+ return NextResponse.json({ error: err.message }, { status: 500 });
+ }
+}
diff --git a/app/api/sync/mimecast/route.ts b/app/api/sync/mimecast/route.ts
new file mode 100644
index 0000000..f6aed70
--- /dev/null
+++ b/app/api/sync/mimecast/route.ts
@@ -0,0 +1,40 @@
+import { NextRequest, NextResponse } from 'next/server';
+import { runMimecastFullSync, runMimecastIncrementalSync, getMimecastStats } from '@/lib/services/mimecast-sync-service';
+
+let _syncing = false;
+
+export async function POST(req: NextRequest) {
+ if (_syncing) {
+ return NextResponse.json({ error: 'Sync already in progress' }, { status: 409 });
+ }
+
+ try {
+ const body = await req.json().catch(() => ({}));
+ const syncType = body.syncType ?? 'incremental';
+
+ _syncing = true;
+
+ const result = syncType === 'full'
+ ? await runMimecastFullSync()
+ : await runMimecastIncrementalSync();
+
+ return NextResponse.json({
+ success: true,
+ syncType,
+ ...result,
+ });
+ } catch (err: any) {
+ return NextResponse.json({ error: err.message }, { status: 500 });
+ } finally {
+ _syncing = false;
+ }
+}
+
+export async function GET() {
+ try {
+ const stats = await getMimecastStats();
+ return NextResponse.json({ isSyncing: _syncing, ...stats });
+ } catch (err: any) {
+ return NextResponse.json({ error: err.message }, { status: 500 });
+ }
+}
diff --git a/dev/mimecast-api-v2-collection.json b/dev/mimecast-api-v2-collection.json
new file mode 100644
index 0000000..20aae1b
--- /dev/null
+++ b/dev/mimecast-api-v2-collection.json
@@ -0,0 +1,110827 @@
+{
+ "info": {
+ "_postman_id": "e8d32b89-98ab-40a0-8541-950be5556d7f",
+ "name": "Mimecast API 2.0 - 2024-11-06",
+ "description": "Interact with Mimecast via the API 2.0 gateway.\n\nContact Support:\n Name: Mimecast Support",
+ "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json",
+ "_exporter_id": "1421581"
+ },
+ "item": [
+ {
+ "name": "api",
+ "item": [
+ {
+ "name": "account",
+ "item": [
+ {
+ "name": "get-account",
+ "item": [
+ {
+ "name": "Account Get Account",
+ "request": {
+ "method": "POST",
+ "header": [
+ {
+ "key": "Accept",
+ "value": "application/json"
+ }
+ ],
+ "url": {
+ "raw": "{{baseUrl}}/api/account/get-account",
+ "host": [
+ "{{baseUrl}}"
+ ],
+ "path": [
+ "api",
+ "account",
+ "get-account"
+ ]
+ },
+ "description": " This endpoint returns the summary details for an account in Mimecast. Pre-requisites In order to successfully use this endpoint the role assigned to the app must have at least the following level of application permissions granted Account | Dashboard | Read . "
+ },
+ "response": [
+ {
+ "name": "The request was processed and executed. This does not mean that the requested action was successful. Function-level success or failure is indicated in the response body content.",
+ "originalRequest": {
+ "method": "POST",
+ "header": [
+ {
+ "key": "Accept",
+ "value": "application/json"
+ }
+ ],
+ "url": {
+ "raw": "{{baseUrl}}/api/account/get-account",
+ "host": [
+ "{{baseUrl}}"
+ ],
+ "path": [
+ "api",
+ "account",
+ "get-account"
+ ]
+ }
+ },
+ "status": "OK",
+ "code": 200,
+ "_postman_previewlanguage": "json",
+ "header": [
+ {
+ "key": "Content-Type",
+ "value": "application/json"
+ },
+ {
+ "key": "x-request-id",
+ "value": "",
+ "description": {
+ "content": "The unique identifier for this API call",
+ "type": "text/plain"
+ }
+ },
+ {
+ "key": "date",
+ "value": "",
+ "description": {
+ "content": "Timestamp of the API call",
+ "type": "text/plain"
+ }
+ }
+ ],
+ "cookie": [],
+ "body": "{\n \"data\": [\n {\n \"accountCode\": \"\",\n \"accountName\": \"\",\n \"adminEmail\": \"\",\n \"archive\": \"\",\n \"automatedSegmentPurge\": \"\",\n \"databaseCode\": \"\",\n \"domain\": \"\",\n \"gateway\": \"\",\n \"mailPlatform\": \"\",\n \"maxRetention\": \"\",\n \"maxRetentionConfirmed\": \"\",\n \"mimecastId\": \"\",\n \"packages\": [\n \"\",\n \"\"\n ],\n \"passphrase\": \"\",\n \"policyInheritance\": \"\",\n \"region\": \"\",\n \"type\": \"\",\n \"userCount\": \"\"\n },\n {\n \"accountCode\": \"\",\n \"accountName\": \"\",\n \"adminEmail\": \"\",\n \"archive\": \"\",\n \"automatedSegmentPurge\": \"\",\n \"databaseCode\": \"\",\n \"domain\": \"\",\n \"gateway\": \"\",\n \"mailPlatform\": \"\",\n \"maxRetention\": \"\",\n \"maxRetentionConfirmed\": \"\",\n \"mimecastId\": \"\",\n \"packages\": [\n \"\",\n \"\"\n ],\n \"passphrase\": \"\",\n \"policyInheritance\": \"\",\n \"region\": \"\",\n \"type\": \"\",\n \"userCount\": \"\"\n }\n ],\n \"fail\": [\n {\n \"errors\": [\n {\n \"code\": \"\",\n \"message\": \"\",\n \"retryable\": \"\"\n },\n {\n \"code\": \"\",\n \"message\": \"\",\n \"retryable\": \"\"\n }\n ],\n \"key\": {}\n },\n {\n \"errors\": [\n {\n \"code\": \"\",\n \"message\": \"\",\n \"retryable\": \"\"\n },\n {\n \"code\": \"\",\n \"message\": \"\",\n \"retryable\": \"\"\n }\n ],\n \"key\": {}\n }\n ]\n}"
+ },
+ {
+ "name": "The request cannot be processed because it is either malformed or not correct.",
+ "originalRequest": {
+ "method": "POST",
+ "header": [
+ {
+ "key": "Accept",
+ "value": "application/json"
+ }
+ ],
+ "url": {
+ "raw": "{{baseUrl}}/api/account/get-account",
+ "host": [
+ "{{baseUrl}}"
+ ],
+ "path": [
+ "api",
+ "account",
+ "get-account"
+ ]
+ }
+ },
+ "status": "Bad Request",
+ "code": 400,
+ "_postman_previewlanguage": "json",
+ "header": [
+ {
+ "key": "Content-Type",
+ "value": "application/json"
+ },
+ {
+ "key": "x-request-id",
+ "value": "",
+ "description": {
+ "content": "The unique identifier for this API call",
+ "type": "text/plain"
+ }
+ },
+ {
+ "key": "date",
+ "value": "",
+ "description": {
+ "content": "Timestamp of the API call",
+ "type": "text/plain"
+ }
+ }
+ ],
+ "cookie": [],
+ "body": "{\n \"fail\": [\n {\n \"errors\": [\n {\n \"code\": \"\",\n \"message\": \"\",\n \"retryable\": \"\"\n },\n {\n \"code\": \"\",\n \"message\": \"\",\n \"retryable\": \"\"\n }\n ],\n \"key\": {}\n },\n {\n \"errors\": [\n {\n \"code\": \"\",\n \"message\": \"\",\n \"retryable\": \"\"\n },\n {\n \"code\": \"\",\n \"message\": \"\",\n \"retryable\": \"\"\n }\n ],\n \"key\": {}\n }\n ]\n}"
+ },
+ {
+ "name": "Authorization information is either missing, incomplete or incorrect.",
+ "originalRequest": {
+ "method": "POST",
+ "header": [
+ {
+ "key": "Accept",
+ "value": "application/json"
+ }
+ ],
+ "url": {
+ "raw": "{{baseUrl}}/api/account/get-account",
+ "host": [
+ "{{baseUrl}}"
+ ],
+ "path": [
+ "api",
+ "account",
+ "get-account"
+ ]
+ }
+ },
+ "status": "Unauthorized",
+ "code": 401,
+ "_postman_previewlanguage": "json",
+ "header": [
+ {
+ "key": "Content-Type",
+ "value": "application/json"
+ },
+ {
+ "key": "x-request-id",
+ "value": "",
+ "description": {
+ "content": "The unique identifier for this API call",
+ "type": "text/plain"
+ }
+ },
+ {
+ "key": "date",
+ "value": "",
+ "description": {
+ "content": "Timestamp of the API call",
+ "type": "text/plain"
+ }
+ }
+ ],
+ "cookie": [],
+ "body": "{\n \"fail\": [\n {\n \"errors\": [\n {\n \"code\": \"\",\n \"message\": \"\",\n \"retryable\": \"\"\n },\n {\n \"code\": \"\",\n \"message\": \"\",\n \"retryable\": \"\"\n }\n ],\n \"key\": {}\n },\n {\n \"errors\": [\n {\n \"code\": \"\",\n \"message\": \"\",\n \"retryable\": \"\"\n },\n {\n \"code\": \"\",\n \"message\": \"\",\n \"retryable\": \"\"\n }\n ],\n \"key\": {}\n }\n ]\n}"
+ },
+ {
+ "name": "Access is denied to the requested resource. The user may not have enough permission to perform the action.",
+ "originalRequest": {
+ "method": "POST",
+ "header": [
+ {
+ "key": "Accept",
+ "value": "application/json"
+ }
+ ],
+ "url": {
+ "raw": "{{baseUrl}}/api/account/get-account",
+ "host": [
+ "{{baseUrl}}"
+ ],
+ "path": [
+ "api",
+ "account",
+ "get-account"
+ ]
+ }
+ },
+ "status": "Forbidden",
+ "code": 403,
+ "_postman_previewlanguage": "json",
+ "header": [
+ {
+ "key": "Content-Type",
+ "value": "application/json"
+ },
+ {
+ "key": "x-request-id",
+ "value": "",
+ "description": {
+ "content": "The unique identifier for this API call",
+ "type": "text/plain"
+ }
+ },
+ {
+ "key": "date",
+ "value": "",
+ "description": {
+ "content": "Timestamp of the API call",
+ "type": "text/plain"
+ }
+ }
+ ],
+ "cookie": [],
+ "body": "{\n \"fail\": [\n {\n \"errors\": [\n {\n \"code\": \"\",\n \"message\": \"\",\n \"retryable\": \"\"\n },\n {\n \"code\": \"\",\n \"message\": \"\",\n \"retryable\": \"\"\n }\n ],\n \"key\": {}\n },\n {\n \"errors\": [\n {\n \"code\": \"\",\n \"message\": \"\",\n \"retryable\": \"\"\n },\n {\n \"code\": \"\",\n \"message\": \"\",\n \"retryable\": \"\"\n }\n ],\n \"key\": {}\n }\n ]\n}"
+ },
+ {
+ "name": "The requested resource does not exist.",
+ "originalRequest": {
+ "method": "POST",
+ "header": [
+ {
+ "key": "Accept",
+ "value": "application/json"
+ }
+ ],
+ "url": {
+ "raw": "{{baseUrl}}/api/account/get-account",
+ "host": [
+ "{{baseUrl}}"
+ ],
+ "path": [
+ "api",
+ "account",
+ "get-account"
+ ]
+ }
+ },
+ "status": "Not Found",
+ "code": 404,
+ "_postman_previewlanguage": "json",
+ "header": [
+ {
+ "key": "Content-Type",
+ "value": "application/json"
+ },
+ {
+ "key": "x-request-id",
+ "value": "",
+ "description": {
+ "content": "The unique identifier for this API call",
+ "type": "text/plain"
+ }
+ },
+ {
+ "key": "date",
+ "value": "",
+ "description": {
+ "content": "Timestamp of the API call",
+ "type": "text/plain"
+ }
+ }
+ ],
+ "cookie": [],
+ "body": "{\n \"fail\": [\n {\n \"errors\": [\n {\n \"code\": \"\",\n \"message\": \"\",\n \"retryable\": \"\"\n },\n {\n \"code\": \"\",\n \"message\": \"\",\n \"retryable\": \"\"\n }\n ],\n \"key\": {}\n },\n {\n \"errors\": [\n {\n \"code\": \"\",\n \"message\": \"\",\n \"retryable\": \"\"\n },\n {\n \"code\": \"\",\n \"message\": \"\",\n \"retryable\": \"\"\n }\n ],\n \"key\": {}\n }\n ]\n}"
+ },
+ {
+ "name": "The current status of the relying data does not match what is defined in the request.",
+ "originalRequest": {
+ "method": "POST",
+ "header": [
+ {
+ "key": "Accept",
+ "value": "application/json"
+ }
+ ],
+ "url": {
+ "raw": "{{baseUrl}}/api/account/get-account",
+ "host": [
+ "{{baseUrl}}"
+ ],
+ "path": [
+ "api",
+ "account",
+ "get-account"
+ ]
+ }
+ },
+ "status": "Conflict",
+ "code": 409,
+ "_postman_previewlanguage": "json",
+ "header": [
+ {
+ "key": "Content-Type",
+ "value": "application/json"
+ },
+ {
+ "key": "x-request-id",
+ "value": "",
+ "description": {
+ "content": "The unique identifier for this API call",
+ "type": "text/plain"
+ }
+ },
+ {
+ "key": "date",
+ "value": "",
+ "description": {
+ "content": "Timestamp of the API call",
+ "type": "text/plain"
+ }
+ }
+ ],
+ "cookie": [],
+ "body": "{\n \"fail\": [\n {\n \"errors\": [\n {\n \"code\": \"\",\n \"message\": \"\",\n \"retryable\": \"\"\n },\n {\n \"code\": \"\",\n \"message\": \"\",\n \"retryable\": \"\"\n }\n ],\n \"key\": {}\n },\n {\n \"errors\": [\n {\n \"code\": \"\",\n \"message\": \"\",\n \"retryable\": \"\"\n },\n {\n \"code\": \"\",\n \"message\": \"\",\n \"retryable\": \"\"\n }\n ],\n \"key\": {}\n }\n ]\n}"
+ },
+ {
+ "name": "Quota Exceeded\tThe number of requests sent to the given resource has exceeded the rate limiting policy applied to the resource for a given time period. Rate limiting is applied differently per resource and is subject to change.",
+ "originalRequest": {
+ "method": "POST",
+ "header": [
+ {
+ "key": "Accept",
+ "value": "application/json"
+ }
+ ],
+ "url": {
+ "raw": "{{baseUrl}}/api/account/get-account",
+ "host": [
+ "{{baseUrl}}"
+ ],
+ "path": [
+ "api",
+ "account",
+ "get-account"
+ ]
+ }
+ },
+ "status": "Too Many Requests",
+ "code": 429,
+ "_postman_previewlanguage": "json",
+ "header": [
+ {
+ "key": "Content-Type",
+ "value": "application/json"
+ },
+ {
+ "key": "x-request-id",
+ "value": "",
+ "description": {
+ "content": "The unique identifier for this API call",
+ "type": "text/plain"
+ }
+ },
+ {
+ "key": "date",
+ "value": "",
+ "description": {
+ "content": "Timestamp of the API call",
+ "type": "text/plain"
+ }
+ }
+ ],
+ "cookie": [],
+ "body": "{\n \"fail\": [\n {\n \"errors\": [\n {\n \"code\": \"\",\n \"message\": \"\",\n \"retryable\": \"\"\n },\n {\n \"code\": \"\",\n \"message\": \"\",\n \"retryable\": \"\"\n }\n ],\n \"key\": {}\n },\n {\n \"errors\": [\n {\n \"code\": \"\",\n \"message\": \"\",\n \"retryable\": \"\"\n },\n {\n \"code\": \"\",\n \"message\": \"\",\n \"retryable\": \"\"\n }\n ],\n \"key\": {}\n }\n ]\n}"
+ },
+ {
+ "name": "The request was not processed successfully or an issue has occurred in the Mimecast platform.",
+ "originalRequest": {
+ "method": "POST",
+ "header": [
+ {
+ "key": "Accept",
+ "value": "application/json"
+ }
+ ],
+ "url": {
+ "raw": "{{baseUrl}}/api/account/get-account",
+ "host": [
+ "{{baseUrl}}"
+ ],
+ "path": [
+ "api",
+ "account",
+ "get-account"
+ ]
+ }
+ },
+ "status": "Internal Server Error",
+ "code": 500,
+ "_postman_previewlanguage": "json",
+ "header": [
+ {
+ "key": "Content-Type",
+ "value": "application/json"
+ },
+ {
+ "key": "x-request-id",
+ "value": "",
+ "description": {
+ "content": "The unique identifier for this API call",
+ "type": "text/plain"
+ }
+ },
+ {
+ "key": "date",
+ "value": "",
+ "description": {
+ "content": "Timestamp of the API call",
+ "type": "text/plain"
+ }
+ }
+ ],
+ "cookie": [],
+ "body": "{\n \"fail\": [\n {\n \"errors\": [\n {\n \"code\": \"\",\n \"message\": \"\",\n \"retryable\": \"\"\n },\n {\n \"code\": \"\",\n \"message\": \"\",\n \"retryable\": \"\"\n }\n ],\n \"key\": {}\n },\n {\n \"errors\": [\n {\n \"code\": \"\",\n \"message\": \"\",\n \"retryable\": \"\"\n },\n {\n \"code\": \"\",\n \"message\": \"\",\n \"retryable\": \"\"\n }\n ],\n \"key\": {}\n }\n ]\n}"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "get-dashboard-notifications",
+ "item": [
+ {
+ "name": "Account Get Dashboard Notifications",
+ "request": {
+ "method": "POST",
+ "header": [
+ {
+ "key": "Content-Type",
+ "value": "application/json"
+ },
+ {
+ "key": "Accept",
+ "value": "application/json"
+ }
+ ],
+ "body": {
+ "mode": "raw",
+ "raw": "{\n \"data\": [\n {\n \"accountCode\": \"\"\n }\n ]\n}",
+ "options": {
+ "raw": {
+ "headerFamily": "json",
+ "language": "json"
+ }
+ }
+ },
+ "url": {
+ "raw": "{{baseUrl}}/api/account/get-dashboard-notifications",
+ "host": [
+ "{{baseUrl}}"
+ ],
+ "path": [
+ "api",
+ "account",
+ "get-dashboard-notifications"
+ ]
+ },
+ "description": " This feed can be used to return dashboard notifications from the Administration Console Dashboard. Pre-requisites In order to successfully use this endpoint the role assigned to the app must have at least the following level of application permissions granted Account | Dashboard | Read . "
+ },
+ "response": [
+ {
+ "name": "The request was processed and executed. This does not mean that the requested action was successful. Function-level success or failure is indicated in the response body content.",
+ "originalRequest": {
+ "method": "POST",
+ "header": [
+ {
+ "key": "Content-Type",
+ "value": "application/json"
+ },
+ {
+ "key": "Accept",
+ "value": "application/json"
+ }
+ ],
+ "body": {
+ "mode": "raw",
+ "raw": "{\n \"data\": [\n {\n \"accountCode\": \"\"\n }\n ]\n}",
+ "options": {
+ "raw": {
+ "headerFamily": "json",
+ "language": "json"
+ }
+ }
+ },
+ "url": {
+ "raw": "{{baseUrl}}/api/account/get-dashboard-notifications",
+ "host": [
+ "{{baseUrl}}"
+ ],
+ "path": [
+ "api",
+ "account",
+ "get-dashboard-notifications"
+ ]
+ }
+ },
+ "status": "OK",
+ "code": 200,
+ "_postman_previewlanguage": "json",
+ "header": [
+ {
+ "key": "Content-Type",
+ "value": "application/json"
+ },
+ {
+ "key": "x-request-id",
+ "value": "",
+ "description": {
+ "content": "The unique identifier for this API call",
+ "type": "text/plain"
+ }
+ },
+ {
+ "key": "date",
+ "value": "",
+ "description": {
+ "content": "Timestamp of the API call",
+ "type": "text/plain"
+ }
+ }
+ ],
+ "cookie": [],
+ "body": "{\n \"data\": [\n {\n \"notifications\": [\n {\n \"clusterCode\": \"\",\n \"customerCode\": \"\",\n \"displayMessage\": \"\",\n \"enabled\": \"\",\n \"id\": \"\",\n \"noticeType\": \"\",\n \"title\": \"\",\n \"visibleFrom\": \"\",\n \"warningLevel\": \"\"\n },\n {\n \"clusterCode\": \"\",\n \"customerCode\": \"\",\n \"displayMessage\": \"\",\n \"enabled\": \"\",\n \"id\": \"\",\n \"noticeType\": \"\",\n \"title\": \"\",\n \"visibleFrom\": \"\",\n \"warningLevel\": \"\"\n }\n ]\n },\n {\n \"notifications\": [\n {\n \"clusterCode\": \"\",\n \"customerCode\": \"\",\n \"displayMessage\": \"\",\n \"enabled\": \"\",\n \"id\": \"\",\n \"noticeType\": \"\",\n \"title\": \"\",\n \"visibleFrom\": \"\",\n \"warningLevel\": \"\"\n },\n {\n \"clusterCode\": \"\",\n \"customerCode\": \"\",\n \"displayMessage\": \"\",\n \"enabled\": \"\",\n \"id\": \"\",\n \"noticeType\": \"\",\n \"title\": \"\",\n \"visibleFrom\": \"\",\n \"warningLevel\": \"\"\n }\n ]\n }\n ],\n \"fail\": [\n {\n \"errors\": [\n {\n \"code\": \"\",\n \"message\": \"\",\n \"retryable\": \"\"\n },\n {\n \"code\": \"\",\n \"message\": \"\",\n \"retryable\": \"\"\n }\n ],\n \"key\": {\n \"accountCode\": \"\"\n }\n },\n {\n \"errors\": [\n {\n \"code\": \"\",\n \"message\": \"\",\n \"retryable\": \"\"\n },\n {\n \"code\": \"\",\n \"message\": \"\",\n \"retryable\": \"\"\n }\n ],\n \"key\": {\n \"accountCode\": \"\"\n }\n }\n ]\n}"
+ },
+ {
+ "name": "The request cannot be processed because it is either malformed or not correct.",
+ "originalRequest": {
+ "method": "POST",
+ "header": [
+ {
+ "key": "Content-Type",
+ "value": "application/json"
+ },
+ {
+ "key": "Accept",
+ "value": "application/json"
+ }
+ ],
+ "body": {
+ "mode": "raw",
+ "raw": "{\n \"data\": [\n {\n \"accountCode\": \"\"\n }\n ]\n}",
+ "options": {
+ "raw": {
+ "headerFamily": "json",
+ "language": "json"
+ }
+ }
+ },
+ "url": {
+ "raw": "{{baseUrl}}/api/account/get-dashboard-notifications",
+ "host": [
+ "{{baseUrl}}"
+ ],
+ "path": [
+ "api",
+ "account",
+ "get-dashboard-notifications"
+ ]
+ }
+ },
+ "status": "Bad Request",
+ "code": 400,
+ "_postman_previewlanguage": "json",
+ "header": [
+ {
+ "key": "Content-Type",
+ "value": "application/json"
+ },
+ {
+ "key": "x-request-id",
+ "value": "",
+ "description": {
+ "content": "The unique identifier for this API call",
+ "type": "text/plain"
+ }
+ },
+ {
+ "key": "date",
+ "value": "",
+ "description": {
+ "content": "Timestamp of the API call",
+ "type": "text/plain"
+ }
+ }
+ ],
+ "cookie": [],
+ "body": "{\n \"fail\": [\n {\n \"errors\": [\n {\n \"code\": \"\",\n \"message\": \"\",\n \"retryable\": \"\"\n },\n {\n \"code\": \"\",\n \"message\": \"\",\n \"retryable\": \"\"\n }\n ],\n \"key\": {\n \"accountCode\": \"\"\n }\n },\n {\n \"errors\": [\n {\n \"code\": \"\",\n \"message\": \"\",\n \"retryable\": \"\"\n },\n {\n \"code\": \"\",\n \"message\": \"\",\n \"retryable\": \"\"\n }\n ],\n \"key\": {\n \"accountCode\": \"\"\n }\n }\n ]\n}"
+ },
+ {
+ "name": "Authorization information is either missing, incomplete or incorrect.",
+ "originalRequest": {
+ "method": "POST",
+ "header": [
+ {
+ "key": "Content-Type",
+ "value": "application/json"
+ },
+ {
+ "key": "Accept",
+ "value": "application/json"
+ }
+ ],
+ "body": {
+ "mode": "raw",
+ "raw": "{\n \"data\": [\n {\n \"accountCode\": \"\"\n }\n ]\n}",
+ "options": {
+ "raw": {
+ "headerFamily": "json",
+ "language": "json"
+ }
+ }
+ },
+ "url": {
+ "raw": "{{baseUrl}}/api/account/get-dashboard-notifications",
+ "host": [
+ "{{baseUrl}}"
+ ],
+ "path": [
+ "api",
+ "account",
+ "get-dashboard-notifications"
+ ]
+ }
+ },
+ "status": "Unauthorized",
+ "code": 401,
+ "_postman_previewlanguage": "json",
+ "header": [
+ {
+ "key": "Content-Type",
+ "value": "application/json"
+ },
+ {
+ "key": "x-request-id",
+ "value": "",
+ "description": {
+ "content": "The unique identifier for this API call",
+ "type": "text/plain"
+ }
+ },
+ {
+ "key": "date",
+ "value": "",
+ "description": {
+ "content": "Timestamp of the API call",
+ "type": "text/plain"
+ }
+ }
+ ],
+ "cookie": [],
+ "body": "{\n \"fail\": [\n {\n \"errors\": [\n {\n \"code\": \"\",\n \"message\": \"\",\n \"retryable\": \"\"\n },\n {\n \"code\": \"\",\n \"message\": \"\",\n \"retryable\": \"\"\n }\n ],\n \"key\": {\n \"accountCode\": \"\"\n }\n },\n {\n \"errors\": [\n {\n \"code\": \"\",\n \"message\": \"\",\n \"retryable\": \"\"\n },\n {\n \"code\": \"\",\n \"message\": \"\",\n \"retryable\": \"\"\n }\n ],\n \"key\": {\n \"accountCode\": \"\"\n }\n }\n ]\n}"
+ },
+ {
+ "name": "Access is denied to the requested resource. The user may not have enough permission to perform the action.",
+ "originalRequest": {
+ "method": "POST",
+ "header": [
+ {
+ "key": "Content-Type",
+ "value": "application/json"
+ },
+ {
+ "key": "Accept",
+ "value": "application/json"
+ }
+ ],
+ "body": {
+ "mode": "raw",
+ "raw": "{\n \"data\": [\n {\n \"accountCode\": \"\"\n }\n ]\n}",
+ "options": {
+ "raw": {
+ "headerFamily": "json",
+ "language": "json"
+ }
+ }
+ },
+ "url": {
+ "raw": "{{baseUrl}}/api/account/get-dashboard-notifications",
+ "host": [
+ "{{baseUrl}}"
+ ],
+ "path": [
+ "api",
+ "account",
+ "get-dashboard-notifications"
+ ]
+ }
+ },
+ "status": "Forbidden",
+ "code": 403,
+ "_postman_previewlanguage": "json",
+ "header": [
+ {
+ "key": "Content-Type",
+ "value": "application/json"
+ },
+ {
+ "key": "x-request-id",
+ "value": "",
+ "description": {
+ "content": "The unique identifier for this API call",
+ "type": "text/plain"
+ }
+ },
+ {
+ "key": "date",
+ "value": "",
+ "description": {
+ "content": "Timestamp of the API call",
+ "type": "text/plain"
+ }
+ }
+ ],
+ "cookie": [],
+ "body": "{\n \"fail\": [\n {\n \"errors\": [\n {\n \"code\": \"\",\n \"message\": \"\",\n \"retryable\": \"\"\n },\n {\n \"code\": \"\",\n \"message\": \"