@lap v0.3
# Machine-readable API spec. Each @endpoint block is one API call.
@api Novu API
@base https://api.novu.co
@version 3.19.2
@auth ApiKey Authorization in header
@endpoints 149
@hint download_for_search
@toc environments(7), events(4), notifications(2), agents(11), domains(15), integrations(13), contexts(5), subscribers(35), layouts(8), messages(3), topics(11), environment-variables(6), workflows(9), channel-connections(5), channel-endpoints(5), translations(9), inbound-webhooks(1)

@group environments
@endpoint POST /v1/environments
@required {name: str, color: str}
@optional {parentId: str}
@returns(201) {data: map{_id: str, name: str, _organizationId: str, identifier: str, type: str?, apiKeys: [map], _parentId: str, slug: str}}
@errors {400, 401, 402, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint GET /v1/environments
@returns(200) {data: [map]}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint PUT /v1/environments/{environmentId}
@required {environmentId: str}
@optional {name: str, identifier: str, parentId: str, color: str, dns: map{inboundParseDomain: str}, bridge: map{url: str}}
@returns(200) {data: map{_id: str, name: str, _organizationId: str, identifier: str, type: str?, apiKeys: [map], _parentId: str, slug: str}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint DELETE /v1/environments/{environmentId}
@required {environmentId: str}
@returns(200)
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endgroup

@group events
@endpoint POST /v1/events/trigger
@required {name: str, to: any}
@optional {payload: map, bridgeUrl: str, overrides: any, agentId: str, transactionId: str, actor: any, tenant: any, context: map}
@returns(201) {data: map{acknowledged: bool, status: str, error: [str], transactionId: str, activityFeedLink: str, jobData: map}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint POST /v1/events/trigger/bulk
@required {events: [map{name!: str, payload: map, bridgeUrl: str, overrides: any, agentId: str, to!: any, transactionId: str, actor: any, tenant: any, context: map}]}
@returns(201) {data: [map]}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint POST /v1/events/trigger/broadcast
@required {name: str, payload: map}
@optional {overrides: any, agentId: str, transactionId: str, actor: any, tenant: any, context: map}
@returns(200) {data: map{acknowledged: bool, status: str, error: [str], transactionId: str, activityFeedLink: str, jobData: map}}
@returns(201) {acknowledged: bool, status: str, error: [str], transactionId: str, activityFeedLink: str, jobData: map}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint DELETE /v1/events/trigger/{transactionId}
@required {transactionId: str}
@returns(200)
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endgroup

@group notifications
@endpoint GET /v1/notifications
@optional {channels: [str], templates: [str], emails: [str], search: str, subscriberIds: [str], severity: [str], page: num=0, limit: num=10, transactionId: str, topicKey: str, subscriptionId: str, contextKeys: [str], after: str, before: str}
@returns(200) {hasMore: bool, data: [map], pageSize: num, page: num}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint GET /v1/notifications/{notificationId}
@required {notificationId: str}
@returns(200) {data: map{_id: str, _environmentId: str, _organizationId: str, _subscriberId: str, transactionId: str, _templateId: str, _digestedNotificationId: str, createdAt: str, updatedAt: str, channels: [str], subscriber: any, template: any, jobs: [map], payload: map, tags: [str], controls: map, to: map, topics: [map], severity: str, critical: bool, contextKeys: [str]}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endgroup

@group agents
@endpoint POST /v1/agents
@required {Novu-Analytics-Source: str, name: str, identifier: str}
@optional {description: str, active: bool=true, runtime: str(self-hosted/managed), managedRuntime: map{providerId!: str, integrationId!: str, externalAgentId: str, externalEnvironmentId: str, model: str, systemPrompt: str, tools: [str], mcpServers: [str], skills: [map]}}
@returns(201) {data: map{_id: str, name: str, identifier: str, description: str, behavior: map{acknowledgeOnReceived: bool, reactionOnResolved: map?, subscriberAccess: str}, active: bool, bridgeUrl: str, devBridgeUrl: str, devBridgeActive: bool, runtime: str, visibility: str, managedRuntime: any, _environmentId: str, _organizationId: str, createdBy: str, createdAt: str, updatedAt: str, integrations: [map], exceedsPlanLimit: bool}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint GET /v1/agents
@optional {after: str, before: str, limit: num, orderDirection: str(ASC/DESC), orderBy: str, includeCursor: bool, identifier: str}
@returns(200) {data: map{data: [map], next: str?, previous: str?, totalCount: num, totalCountCapped: bool, planUsage: any}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint PUT /v1/agents/{identifier}/bridge
@required {identifier: str}
@optional {bridgeUrl: str, devBridgeUrl: str, devBridgeActive: bool}
@returns(200) {data: map{_id: str, name: str, identifier: str, description: str, behavior: map{acknowledgeOnReceived: bool, reactionOnResolved: map?, subscriberAccess: str}, active: bool, bridgeUrl: str, devBridgeUrl: str, devBridgeActive: bool, runtime: str, visibility: str, managedRuntime: any, _environmentId: str, _organizationId: str, createdBy: str, createdAt: str, updatedAt: str, integrations: [map], exceedsPlanLimit: bool}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint GET /v1/agents/{identifier}
@required {identifier: str}
@returns(200) {data: map{_id: str, name: str, identifier: str, description: str, behavior: map{acknowledgeOnReceived: bool, reactionOnResolved: map?, subscriberAccess: str}, active: bool, bridgeUrl: str, devBridgeUrl: str, devBridgeActive: bool, runtime: str, visibility: str, managedRuntime: any, _environmentId: str, _organizationId: str, createdBy: str, createdAt: str, updatedAt: str, integrations: [map], exceedsPlanLimit: bool}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint PATCH /v1/agents/{identifier}
@required {identifier: str}
@optional {name: str, description: str, active: bool, behavior: map{acknowledgeOnReceived: bool, reactionOnResolved: map, subscriberAccess: str}, bridgeUrl: str, devBridgeUrl: str, devBridgeActive: bool}
@returns(200) {data: map{_id: str, name: str, identifier: str, description: str, behavior: map{acknowledgeOnReceived: bool, reactionOnResolved: map?, subscriberAccess: str}, active: bool, bridgeUrl: str, devBridgeUrl: str, devBridgeActive: bool, runtime: str, visibility: str, managedRuntime: any, _environmentId: str, _organizationId: str, createdBy: str, createdAt: str, updatedAt: str, integrations: [map], exceedsPlanLimit: bool}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint DELETE /v1/agents/{identifier}
@required {identifier: str, deleteFromProvider: str}
@returns(204)
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint POST /v1/agents/{identifier}/integrations
@required {identifier: str}
@optional {integrationIdentifier: str, providerId: str}
@returns(201) {data: map{_id: str, _agentId: str, integration: map{_id: str, identifier: str, name: str, providerId: str, channel: str, active: bool, sharedInboundAddress: str, defaultSenderName: str, sharedInboxDisabled: bool}, _environmentId: str, _organizationId: str, connectedAt: map?, createdAt: str, updatedAt: str, exceedsPlanLimit: bool}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint GET /v1/agents/{identifier}/integrations
@required {identifier: str}
@optional {after: str, before: str, limit: num, orderDirection: str(ASC/DESC), orderBy: str, includeCursor: bool, integrationIdentifier: str}
@returns(200) {data: map{data: [map], next: str?, previous: str?, totalCount: num, totalCountCapped: bool, planUsage: any}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint PATCH /v1/agents/{identifier}/integrations/{agentIntegrationId}
@required {identifier: str, agentIntegrationId: str, integrationIdentifier: str}
@returns(200) {data: map{_id: str, _agentId: str, integration: map{_id: str, identifier: str, name: str, providerId: str, channel: str, active: bool, sharedInboundAddress: str, defaultSenderName: str, sharedInboxDisabled: bool}, _environmentId: str, _organizationId: str, connectedAt: map?, createdAt: str, updatedAt: str, exceedsPlanLimit: bool}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint DELETE /v1/agents/{identifier}/integrations/{agentIntegrationId}
@required {identifier: str, agentIntegrationId: str}
@returns(204)
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint POST /v1/agents/{agentId}/reply
@required {agentId: str, conversationId: str, integrationIdentifier: str}
@optional {reply: any, toolApprovalRequest: any, edit: any, resolve: any, signals: [any], toolResults: [map{toolCallId!: str, toolName: str, output: map, preview: str}], addReactions: [map{messageId!: str, emojiName!: str}], deleteMessages: [map{messageId!: str}], typing: any, error: bool}
@returns(200) {data: any?}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endgroup

@group domains
@endpoint GET /v1/domains
@optional {after: str, before: str, limit: num, orderDirection: str(ASC/DESC), orderBy: str, includeCursor: bool, name: str}
@returns(200) {data: map{data: [map], next: str?, previous: str?, totalCount: num, totalCountCapped: bool}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint POST /v1/domains
@required {name: str}
@optional {data: map}
@returns(201) {data: map{_id: str, name: str, status: str, mxRecordConfigured: bool, dnsProvider: str, _environmentId: str, _organizationId: str, createdAt: str, updatedAt: str, expectedDnsRecords: [map], data: map}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint GET /v1/domains/{domain}
@required {domain: str}
@returns(200) {data: map{_id: str, name: str, status: str, mxRecordConfigured: bool, dnsProvider: str, _environmentId: str, _organizationId: str, createdAt: str, updatedAt: str, expectedDnsRecords: [map], data: map}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint PATCH /v1/domains/{domain}
@required {domain: str}
@optional {data: map}
@returns(200) {data: map{_id: str, name: str, status: str, mxRecordConfigured: bool, dnsProvider: str, _environmentId: str, _organizationId: str, createdAt: str, updatedAt: str, expectedDnsRecords: [map], data: map}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint DELETE /v1/domains/{domain}
@required {domain: str}
@returns(204)
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint POST /v1/domains/{domain}/verify
@required {domain: str}
@returns(200) {data: map{_id: str, name: str, status: str, mxRecordConfigured: bool, dnsProvider: str, _environmentId: str, _organizationId: str, createdAt: str, updatedAt: str, expectedDnsRecords: [map], data: map}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint POST /v1/domains/{domain}/diagnose
@required {domain: str}
@returns(200) {data: map{ok: bool, runAt: str, checks: [map], issues: [map]}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint GET /v1/domains/{domain}/routes
@required {domain: str}
@optional {after: str, before: str, limit: num, orderDirection: str(ASC/DESC), orderBy: str, includeCursor: bool, agentId: str}
@returns(200) {data: map{data: [map], next: str?, previous: str?, totalCount: num, totalCountCapped: bool}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint POST /v1/domains/{domain}/routes
@required {domain: str, address: str, type: str(agent/webhook)}
@optional {agentId: str, data: map}
@returns(201) {data: map{_id: str, _domainId: str, address: str, agentId: str, type: str, _environmentId: str, _organizationId: str, createdAt: str, updatedAt: str, data: map}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint GET /v1/domains/{domain}/routes/{address}
@required {domain: str, address: str}
@returns(200) {data: map{_id: str, _domainId: str, address: str, agentId: str, type: str, _environmentId: str, _organizationId: str, createdAt: str, updatedAt: str, data: map}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint PATCH /v1/domains/{domain}/routes/{address}
@required {domain: str, address: str}
@optional {agentId: str, type: str(agent/webhook), data: map}
@returns(200) {data: map{_id: str, _domainId: str, address: str, agentId: str, type: str, _environmentId: str, _organizationId: str, createdAt: str, updatedAt: str, data: map}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint DELETE /v1/domains/{domain}/routes/{address}
@required {domain: str, address: str}
@returns(204)
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint POST /v1/domains/{domain}/routes/{address}/test
@required {domain: str, address: str, from: map{address!: str, name: str}, subject: str}
@optional {text: str, html: str, dryRun: bool}
@returns(200) {data: map{matched: bool, dryRun: bool, domainStatus: str, mxRecordConfigured: bool, type: str, wouldDeliverTo: str, payload: map, webhook: map{skipped: bool, latencyMs: num}, agent: map{agentId: str, httpStatus: num, agentReply: map, latencyMs: num}}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint GET /v1/domains/{domain}/auto-configure
@required {domain: str}
@returns(200) {data: map{available: bool, providerName: str, providerId: str, reason: str, reasonCode: str, manualRecords: [map]}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint POST /v1/domains/{domain}/auto-configure/start
@required {domain: str}
@optional {redirectUri: str}
@returns(201) {data: map{applyUrl: str, providerName: str, redirectUri: str}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endgroup

@group integrations
@endpoint GET /v1/integrations
@returns(200)
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint POST /v1/integrations
@optional {name: str, identifier: str, _environmentId: str(uuid), providerId: str, channel: str(in_app/email/sms/chat/push/tool), kind: str(delivery/agent), credentials: any, active: bool, check: bool, conditions: [map{isNegated!: bool, type!: str, value!: str, children!: [map]}], rules: map, configurations: map}
@returns(201) {data: map{_id: str, _environmentId: str, _organizationId: str, name: str, identifier: str, providerId: str, channel: str, kind: str, credentials: any, configurations: any, active: bool, deleted: bool, deletedAt: str, deletedBy: str, primary: bool, conditions: [map], rules: map?}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint GET /v1/integrations/active
@returns(200)
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint PUT /v1/integrations/{integrationId}
@required {integrationId: str}
@optional {name: str, identifier: str, _environmentId: str, active: bool, credentials: map{apiKey: str, user: str, secretKey: str, hmacSecretKeyEncoding: str, domain: str, password: str, host: str, port: str, secure: bool, region: str, accountSid: str, messageProfileId: str, token: str, from: str, senderName: str, projectName: str, applicationId: str, clientId: str, requireTls: bool, ignoreTls: bool, tlsOptions: map, baseUrl: str, webhookUrl: str, redirectUrl: str, hmac: bool, serviceAccount: str, ipPoolName: str, configurationSetName: str, apiKeyRequestHeader: str, secretKeyRequestHeader: str, idPath: str, datePath: str, apiToken: str, authenticateByToken: bool, authenticationTokenKey: str, instanceId: str, alertUid: str, title: str, imageUrl: str, state: str, externalLink: str, channelId: str, phoneNumberIdentification: str, accessKey: str, appSid: str, senderId: str, tenantId: str, AppIOBaseUrl: str, signingSecret: str, outboundIntegrationId: str, outboundConnectedAt: str, whatsNextCompletedAt: str, useFromAddressOverride: bool, fromAddressOverride: str, emailSlugPrefix: str, externalEnvironmentId: str, externalVaultId: str, externalWorkspaceId: str}, check: bool, conditions: [map{isNegated!: bool, type!: str, value!: str, children!: [map]}], rules: map, configurations: map}
@returns(200) {data: map{_id: str, _environmentId: str, _organizationId: str, name: str, identifier: str, providerId: str, channel: str, kind: str, credentials: any, configurations: any, active: bool, deleted: bool, deletedAt: str, deletedBy: str, primary: bool, conditions: [map], rules: map?}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint DELETE /v1/integrations/{integrationId}
@required {integrationId: str}
@returns(200) {data: [map]}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint POST /v1/integrations/{integrationId}/auto-configure
@required {integrationId: str}
@returns(200) {data: map{success: bool, message: str, integration: map}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint POST /v1/integrations/{integrationId}/set-primary
@required {integrationId: str}
@returns(200) {data: map{_id: str, _environmentId: str, _organizationId: str, name: str, identifier: str, providerId: str, channel: str, kind: str, credentials: any, configurations: any, active: bool, deleted: bool, deletedAt: str, deletedBy: str, primary: bool, conditions: [map], rules: map?}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint POST /v1/integrations/chat/oauth
@required {integrationIdentifier: str}
@optional {subscriberId: str, connectionIdentifier: str, context: map, scope: [str], userScope: [str], mode: str(connect/link_user), connectionMode: str(subscriber/shared), autoLinkUser: bool}
@returns(201) {data: map{url: str}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint POST /v1/integrations/channel-connections/oauth
@required {integrationIdentifier: str}
@optional {subscriberId: str, connectionIdentifier: str, context: map, contextHash: str, scope: [str], connectionMode: str(subscriber/shared), autoLinkUser: bool}
@returns(201) {data: map{url: str}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint POST /v1/integrations/channel-endpoints/oauth
@required {subscriberId: str, integrationIdentifier: str}
@optional {connectionIdentifier: str, context: map, contextHash: str, userScope: [str]}
@returns(201) {data: map{url: str}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint POST /v1/integrations/channel-endpoints/link
@required {integrationIdentifier: str, subscriberId: str}
@optional {context: map, contextHash: str}
@returns(200) {data: map{url: str, providerMetadata: map}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint POST /v1/integrations/{integrationIdentifier}/webhook/configure
@required {integrationIdentifier: str}
@returns(200) {data: map{webhookUrl: str, configuredAt: str, botUsername: str}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint POST /v1/integrations/{integrationIdentifier}/mobile-link
@required {integrationIdentifier: str}
@optional {subscriberId: str}
@returns(200) {data: map{token: str, url: str, expiresAt: str}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endgroup

@group contexts
@endpoint POST /v2/contexts
@required {type: str, id: str}
@optional {data: map, bridgeUrl: str}
@returns(201) {data: map{type: str, id: str, data: map, bridgeUrl: str, createdAt: str, updatedAt: str}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint GET /v2/contexts
@optional {after: str, before: str, limit: num, orderDirection: str(ASC/DESC), orderBy: str, includeCursor: bool, id: str, search: str}
@returns(200) {data: map{data: [map], next: str?, previous: str?, totalCount: num, totalCountCapped: bool}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint PATCH /v2/contexts/{type}/{id}
@required {id: str, type: str, data: map}
@optional {bridgeUrl: str}
@returns(200) {data: map{type: str, id: str, data: map, bridgeUrl: str, createdAt: str, updatedAt: str}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint GET /v2/contexts/{type}/{id}
@required {id: str, type: str}
@returns(200) {data: map{type: str, id: str, data: map, bridgeUrl: str, createdAt: str, updatedAt: str}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint DELETE /v2/contexts/{type}/{id}
@required {id: str, type: str}
@returns(204)
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endgroup

@group subscribers
@endpoint POST /v1/subscribers/bulk
@required {subscribers: [map{firstName: str, lastName: str, email: str, phone: str, avatar: str, locale: str, timezone: str, data: map, subscriberId!: str}]}
@returns(201) {data: map{updated: [map], created: [map], failed: [map]}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint PUT /v1/subscribers/{subscriberId}/credentials
@required {subscriberId: str, providerId: str(slack/discord/msteams/webex-messaging/mattermost/ryver/zulip/grafana-on-call/getstream/rocket-chat/whatsapp-business/line/chat-webhook/novu-slack/telegram/sendblue/novu-web-chat/fcm/apns/expo/one-signal/pushpad/push-webhook/pusher-beams/appio), credentials: any}
@optional {integrationIdentifier: str}
@returns(200) {data: map{_id: str, firstName: str?, lastName: str?, email: str?, phone: str?, avatar: str?, locale: str?, channels: [map], topics: [str], isOnline: bool?, lastOnlineAt: str?, __v: num, data: map?, timezone: str?, subscriberId: str, _organizationId: str, _environmentId: str, deleted: bool, createdAt: str, updatedAt: str}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint PATCH /v1/subscribers/{subscriberId}/credentials
@required {subscriberId: str, providerId: str(slack/discord/msteams/webex-messaging/mattermost/ryver/zulip/grafana-on-call/getstream/rocket-chat/whatsapp-business/line/chat-webhook/novu-slack/telegram/sendblue/novu-web-chat/fcm/apns/expo/one-signal/pushpad/push-webhook/pusher-beams/appio), credentials: any}
@optional {integrationIdentifier: str}
@returns(200) {data: map{_id: str, firstName: str?, lastName: str?, email: str?, phone: str?, avatar: str?, locale: str?, channels: [map], topics: [str], isOnline: bool?, lastOnlineAt: str?, __v: num, data: map?, timezone: str?, subscriberId: str, _organizationId: str, _environmentId: str, deleted: bool, createdAt: str, updatedAt: str}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint DELETE /v1/subscribers/{subscriberId}/credentials/{providerId}
@required {subscriberId: str, providerId: str}
@returns(204)
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint PATCH /v1/subscribers/{subscriberId}/online-status
@required {subscriberId: str, isOnline: bool}
@returns(200) {data: map{_id: str, firstName: str?, lastName: str?, email: str?, phone: str?, avatar: str?, locale: str?, channels: [map], topics: [str], isOnline: bool?, lastOnlineAt: str?, __v: num, data: map?, timezone: str?, subscriberId: str, _organizationId: str, _environmentId: str, deleted: bool, createdAt: str, updatedAt: str}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint GET /v1/subscribers/{subscriberId}/notifications/feed
@required {subscriberId: str}
@optional {page: num, limit: num=10, read: bool, seen: bool, payload: str}
@returns(200) {data: map{totalCount: num, hasMore: bool, data: [map], pageSize: num, page: num}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint GET /v1/subscribers/{subscriberId}/notifications/unseen
@required {subscriberId: str}
@optional {seen: bool=false, limit: num=100}
@returns(200) {data: map{count: num}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint POST /v1/subscribers/{subscriberId}/messages/mark-as
@required {subscriberId: str, messageId: any, markAs: str(read/seen/unread/unseen)}
@returns(201) {data: [map]}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint POST /v1/subscribers/{subscriberId}/messages/mark-all
@required {subscriberId: str, markAs: str(read/seen/unread/unseen)}
@optional {feedIdentifier: any}
@returns(201)
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint POST /v1/subscribers/{subscriberId}/messages/{messageId}/actions/{type}
@required {messageId: str, type: any, subscriberId: str, status: str(pending/done)}
@optional {payload: map}
@returns(201) {data: map{_id: str, _templateId: str?, _environmentId: str, _messageTemplateId: str?, _organizationId: str, _notificationId: str, _subscriberId: str, subscriber: any, template: any, templateIdentifier: str, createdAt: str, deliveredAt: [str], lastSeenDate: str, lastReadDate: str, content: any?, transactionId: str, subject: str, channel: str, read: bool, seen: bool, snoozedUntil: str, email: str, phone: str, directWebhookUrl: str, providerId: str, deviceTokens: [str], title: str, cta: any, _feedId: str?, status: str, errorId: str, errorText: str, payload: map, overrides: map, contextKeys: [str]}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint GET /v2/subscribers
@optional {after: str, before: str, limit: num, orderDirection: str(ASC/DESC), orderBy: str, includeCursor: bool, email: str, name: str, phone: str, subscriberId: str}
@returns(200) {data: map{data: [map], next: str?, previous: str?, totalCount: num, totalCountCapped: bool}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint POST /v2/subscribers
@required {subscriberId: str}
@optional {failIfExists: bool, firstName: str, lastName: str, email: str, phone: str, avatar: str, locale: str, timezone: str, data: map}
@returns(201) {data: map{_id: str, firstName: str?, lastName: str?, email: str?, phone: str?, avatar: str?, locale: str?, channels: [map], topics: [str], isOnline: bool?, lastOnlineAt: str?, __v: num, data: map?, timezone: str?, subscriberId: str, _organizationId: str, _environmentId: str, deleted: bool, createdAt: str, updatedAt: str}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint GET /v2/subscribers/{subscriberId}
@required {subscriberId: str}
@returns(200) {data: map{_id: str, firstName: str?, lastName: str?, email: str?, phone: str?, avatar: str?, locale: str?, channels: [map], topics: [str], isOnline: bool?, lastOnlineAt: str?, __v: num, data: map?, timezone: str?, subscriberId: str, _organizationId: str, _environmentId: str, deleted: bool, createdAt: str, updatedAt: str}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint PATCH /v2/subscribers/{subscriberId}
@required {subscriberId: str}
@optional {firstName: str, lastName: str, email: str, phone: str, avatar: str, locale: str, timezone: str, data: map}
@returns(200) {data: map{_id: str, firstName: str?, lastName: str?, email: str?, phone: str?, avatar: str?, locale: str?, channels: [map], topics: [str], isOnline: bool?, lastOnlineAt: str?, __v: num, data: map?, timezone: str?, subscriberId: str, _organizationId: str, _environmentId: str, deleted: bool, createdAt: str, updatedAt: str}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint DELETE /v2/subscribers/{subscriberId}
@required {subscriberId: str}
@returns(200) {data: map{acknowledged: bool, status: str}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint GET /v2/subscribers/{subscriberId}/preferences
@required {subscriberId: str}
@optional {criticality: str(critical/nonCritical/all)=nonCritical, contextKeys: [str]}
@returns(200) {data: map{global: any, workflows: [map]}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint PATCH /v2/subscribers/{subscriberId}/preferences
@required {subscriberId: str}
@optional {channels: any, workflowId: str, schedule: any, context: map}
@returns(200) {data: map{global: any, workflows: [map]}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint PATCH /v2/subscribers/{subscriberId}/preferences/bulk
@required {subscriberId: str, preferences: [map{channels!: any, workflowId!: str}]}
@optional {context: map}
@returns(200) {data: [map]}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint GET /v2/subscribers/{subscriberId}/subscriptions
@required {subscriberId: str}
@optional {after: str, before: str, limit: num, orderDirection: str(ASC/DESC), orderBy: str, includeCursor: bool, key: str, contextKeys: [str]}
@returns(200) {data: map{data: [map], next: str?, previous: str?, totalCount: num, totalCountCapped: bool}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint GET /v2/subscribers/{subscriberId}/notifications
@required {subscriberId: str}
@optional {limit: num=10, after: str, offset: num, read: bool, archived: bool, snoozed: bool, seen: bool, data: str, severity: [str], createdGte: num, createdLte: num, contextKeys: [str]}
@returns(200) {data: map{data: [map], hasMore: bool, filter: map}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint GET /v2/subscribers/{subscriberId}/notifications/count
@required {subscriberId: str, filters: str}
@returns(200) {data: [map]}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint PATCH /v2/subscribers/{subscriberId}/notifications/{notificationId}/read
@required {subscriberId: str, notificationId: str}
@optional {contextKeys: [str]}
@returns(200) {id: str, transactionId: str, subject: str, body: str, to: any, isRead: bool, isSeen: bool, isArchived: bool, isSnoozed: bool, snoozedUntil: str?, deliveredAt: [str], createdAt: str, readAt: str?, firstSeenAt: str?, archivedAt: str?, avatar: str, primaryAction: any, secondaryAction: any, channelType: str, tags: [str], data: map, redirect: any, workflow: any, severity: str}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint PATCH /v2/subscribers/{subscriberId}/notifications/{notificationId}/unread
@required {subscriberId: str, notificationId: str}
@optional {contextKeys: [str]}
@returns(200) {id: str, transactionId: str, subject: str, body: str, to: any, isRead: bool, isSeen: bool, isArchived: bool, isSnoozed: bool, snoozedUntil: str?, deliveredAt: [str], createdAt: str, readAt: str?, firstSeenAt: str?, archivedAt: str?, avatar: str, primaryAction: any, secondaryAction: any, channelType: str, tags: [str], data: map, redirect: any, workflow: any, severity: str}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint PATCH /v2/subscribers/{subscriberId}/notifications/{notificationId}/archive
@required {subscriberId: str, notificationId: str}
@optional {contextKeys: [str]}
@returns(200) {id: str, transactionId: str, subject: str, body: str, to: any, isRead: bool, isSeen: bool, isArchived: bool, isSnoozed: bool, snoozedUntil: str?, deliveredAt: [str], createdAt: str, readAt: str?, firstSeenAt: str?, archivedAt: str?, avatar: str, primaryAction: any, secondaryAction: any, channelType: str, tags: [str], data: map, redirect: any, workflow: any, severity: str}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint PATCH /v2/subscribers/{subscriberId}/notifications/{notificationId}/unarchive
@required {subscriberId: str, notificationId: str}
@optional {contextKeys: [str]}
@returns(200) {id: str, transactionId: str, subject: str, body: str, to: any, isRead: bool, isSeen: bool, isArchived: bool, isSnoozed: bool, snoozedUntil: str?, deliveredAt: [str], createdAt: str, readAt: str?, firstSeenAt: str?, archivedAt: str?, avatar: str, primaryAction: any, secondaryAction: any, channelType: str, tags: [str], data: map, redirect: any, workflow: any, severity: str}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint PATCH /v2/subscribers/{subscriberId}/notifications/{notificationId}/snooze
@required {subscriberId: str, notificationId: str, snoozeUntil: str(date-time)}
@optional {contextKeys: [str]}
@returns(200) {id: str, transactionId: str, subject: str, body: str, to: any, isRead: bool, isSeen: bool, isArchived: bool, isSnoozed: bool, snoozedUntil: str?, deliveredAt: [str], createdAt: str, readAt: str?, firstSeenAt: str?, archivedAt: str?, avatar: str, primaryAction: any, secondaryAction: any, channelType: str, tags: [str], data: map, redirect: any, workflow: any, severity: str}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint PATCH /v2/subscribers/{subscriberId}/notifications/{notificationId}/unsnooze
@required {subscriberId: str, notificationId: str}
@optional {contextKeys: [str]}
@returns(200) {id: str, transactionId: str, subject: str, body: str, to: any, isRead: bool, isSeen: bool, isArchived: bool, isSnoozed: bool, snoozedUntil: str?, deliveredAt: [str], createdAt: str, readAt: str?, firstSeenAt: str?, archivedAt: str?, avatar: str, primaryAction: any, secondaryAction: any, channelType: str, tags: [str], data: map, redirect: any, workflow: any, severity: str}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint DELETE /v2/subscribers/{subscriberId}/notifications/{notificationId}
@required {subscriberId: str, notificationId: str}
@optional {contextKeys: [str]}
@returns(204)
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint PATCH /v2/subscribers/{subscriberId}/notifications/{notificationId}/actions/{actionType}/complete
@required {subscriberId: str, notificationId: str, actionType: str(primary/secondary)}
@optional {contextKeys: [str]}
@returns(200) {id: str, transactionId: str, subject: str, body: str, to: any, isRead: bool, isSeen: bool, isArchived: bool, isSnoozed: bool, snoozedUntil: str?, deliveredAt: [str], createdAt: str, readAt: str?, firstSeenAt: str?, archivedAt: str?, avatar: str, primaryAction: any, secondaryAction: any, channelType: str, tags: [str], data: map, redirect: any, workflow: any, severity: str}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint PATCH /v2/subscribers/{subscriberId}/notifications/{notificationId}/actions/{actionType}/revert
@required {subscriberId: str, notificationId: str, actionType: str(primary/secondary)}
@optional {contextKeys: [str]}
@returns(200) {id: str, transactionId: str, subject: str, body: str, to: any, isRead: bool, isSeen: bool, isArchived: bool, isSnoozed: bool, snoozedUntil: str?, deliveredAt: [str], createdAt: str, readAt: str?, firstSeenAt: str?, archivedAt: str?, avatar: str, primaryAction: any, secondaryAction: any, channelType: str, tags: [str], data: map, redirect: any, workflow: any, severity: str}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint POST /v2/subscribers/{subscriberId}/notifications/seen
@required {subscriberId: str}
@optional {notificationIds: [str], tags: map, data: str, contextKeys: [str]}
@returns(204)
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint POST /v2/subscribers/{subscriberId}/notifications/read
@required {subscriberId: str}
@optional {tags: map, data: str, contextKeys: [str]}
@returns(204)
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint POST /v2/subscribers/{subscriberId}/notifications/archive
@required {subscriberId: str}
@optional {tags: map, data: str, contextKeys: [str]}
@returns(204)
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint POST /v2/subscribers/{subscriberId}/notifications/read-archive
@required {subscriberId: str}
@optional {tags: map, data: str, contextKeys: [str]}
@returns(204)
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint POST /v2/subscribers/{subscriberId}/notifications/delete
@required {subscriberId: str}
@optional {tags: map, data: str, contextKeys: [str]}
@returns(204)
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endgroup

@group layouts
@endpoint POST /v2/layouts
@required {layoutId: str, name: str}
@optional {isTranslationEnabled: bool=false, __source: str=dashboard}
@returns(201) {data: map{_id: str, layoutId: str, slug: str, name: str, isDefault: bool, isTranslationEnabled: bool, updatedAt: str, updatedBy: any?, createdAt: str, origin: str, type: str, variables: map?, controls: any}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint GET /v2/layouts
@optional {limit: num, offset: num, orderDirection: str, orderBy: str, query: str}
@returns(200) {data: map{layouts: [map], totalCount: num}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint PUT /v2/layouts/{layoutId}
@required {layoutId: str, name: str}
@optional {isTranslationEnabled: bool=false, controlValues: any}
@returns(200) {data: map{_id: str, layoutId: str, slug: str, name: str, isDefault: bool, isTranslationEnabled: bool, updatedAt: str, updatedBy: any?, createdAt: str, origin: str, type: str, variables: map?, controls: any}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint GET /v2/layouts/{layoutId}
@required {layoutId: str}
@returns(200) {data: map{_id: str, layoutId: str, slug: str, name: str, isDefault: bool, isTranslationEnabled: bool, updatedAt: str, updatedBy: any?, createdAt: str, origin: str, type: str, variables: map?, controls: any}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint DELETE /v2/layouts/{layoutId}
@required {layoutId: str}
@returns(204)
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint POST /v2/layouts/{layoutId}/duplicate
@required {layoutId: str, name: str}
@optional {layoutId: str, isTranslationEnabled: bool=false}
@returns(201) {data: map{_id: str, layoutId: str, slug: str, name: str, isDefault: bool, isTranslationEnabled: bool, updatedAt: str, updatedBy: any?, createdAt: str, origin: str, type: str, variables: map?, controls: any}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint POST /v2/layouts/{layoutId}/preview
@required {layoutId: str}
@optional {controlValues: map, previewPayload: any}
@returns(201) {data: map{previewPayloadExample: any, schema: map?, result: any}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint GET /v2/layouts/{layoutId}/usage
@required {layoutId: str}
@returns(200) {data: map{workflows: [map]}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endgroup

@group messages
@endpoint GET /v1/messages
@optional {channel: str, subscriberId: str, transactionId: [str], contextKeys: [str], page: num=0, limit: num=10}
@returns(200) {totalCount: num, hasMore: bool, data: [map], pageSize: num, page: num}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint DELETE /v1/messages/{messageId}
@required {messageId: str}
@returns(200) {data: map{acknowledged: bool, status: str}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint DELETE /v1/messages/transaction/{transactionId}
@required {transactionId: str}
@optional {channel: str(in_app/email/sms/chat/push/tool)}
@returns(204)
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endgroup

@group topics
@endpoint GET /v1/topics/{topicKey}/subscribers/{externalSubscriberId}
@required {externalSubscriberId: str, topicKey: str}
@returns(200) {_organizationId: str, _environmentId: str, _subscriberId: str, _topicId: str, topicKey: str, externalSubscriberId: str}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint GET /v2/topics
@optional {after: str, before: str, limit: num, orderDirection: str(ASC/DESC), orderBy: str, includeCursor: bool, key: str, name: str}
@returns(200) {data: map{data: [map], next: str?, previous: str?, totalCount: num, totalCountCapped: bool}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint POST /v2/topics
@required {key: str}
@optional {failIfExists: bool, name: str, data: map}
@returns(200) {data: map{_id: str, key: str, name: str, data: map, createdAt: str, updatedAt: str}}
@returns(201) {data: map{_id: str, key: str, name: str, data: map, createdAt: str, updatedAt: str}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint GET /v2/topics/{topicKey}
@required {topicKey: str}
@returns(200) {data: map{_id: str, key: str, name: str, data: map, createdAt: str, updatedAt: str}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint PATCH /v2/topics/{topicKey}
@required {topicKey: str}
@optional {name: str, data: map}
@returns(200) {data: map{_id: str, key: str, name: str, data: map, createdAt: str, updatedAt: str}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint DELETE /v2/topics/{topicKey}
@required {topicKey: str}
@returns(200) {data: map{acknowledged: bool}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint GET /v2/topics/{topicKey}/subscriptions
@required {topicKey: str}
@optional {after: str, before: str, limit: num, orderDirection: str(ASC/DESC), orderBy: str, includeCursor: bool, subscriberId: str, contextKeys: [str]}
@returns(200) {data: map{data: [map], next: str?, previous: str?, totalCount: num, totalCountCapped: bool}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint POST /v2/topics/{topicKey}/subscriptions
@required {topicKey: str}
@optional {subscriberIds: [str], subscriptions: [any], name: str, context: map, preferences: [any]}
@returns(201) {data: map{data: [map], meta: any, errors: [map]}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint DELETE /v2/topics/{topicKey}/subscriptions
@required {topicKey: str}
@optional {subscriberIds: [str], subscriptions: [any]}
@returns(200) {data: [map], meta: any, errors: [map]}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint GET /v2/topics/{topicKey}/subscriptions/{identifier}
@required {topicKey: str, identifier: str}
@returns(200) {data: map{id: str, identifier: str, name: str, preferences: [map], contextKeys: [str]}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint PATCH /v2/topics/{topicKey}/subscriptions/{identifier}
@required {topicKey: str, identifier: str}
@optional {name: str, preferences: [any]}
@returns(200) {data: map{_id: str, identifier: str, name: str, topic: any, subscriber: any?, preferences: [map], contextKeys: [str], createdAt: str, updatedAt: str}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endgroup

@group environment-variables
@endpoint GET /v1/environment-variables
@optional {search: str}
@returns(200) {data: [map]}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint POST /v1/environment-variables
@required {key: str}
@optional {type: str, isSecret: bool, values: [map{_environmentId!: str, value!: str}]}
@returns(200) {data: map{_id: str, _organizationId: str, key: str, type: str, isSecret: bool, values: [map], createdAt: str, updatedAt: str}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint GET /v1/environment-variables/{variableKey}/usage
@required {variableKey: str}
@returns(200) {data: map{workflows: [map]}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint GET /v1/environment-variables/{variableKey}
@required {variableKey: str}
@returns(200) {data: map{_id: str, _organizationId: str, key: str, type: str, isSecret: bool, values: [map], createdAt: str, updatedAt: str}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint PATCH /v1/environment-variables/{variableKey}
@required {variableKey: str}
@optional {key: str, type: str, isSecret: bool, values: [map{_environmentId!: str, value!: str}]}
@returns(200) {data: map{_id: str, _organizationId: str, key: str, type: str, isSecret: bool, values: [map], createdAt: str, updatedAt: str}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint DELETE /v1/environment-variables/{variableKey}
@required {variableKey: str}
@returns(204)
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endgroup

@group workflows
@endpoint POST /v2/workflows
@required {name: str, workflowId: str, steps: [any]}
@optional {description: str, tags: [str], active: bool=false, validatePayload: bool, payloadSchema: map, isTranslationEnabled: bool=false, agent: any, __source: str(template_store/editor/notification_directory/onboarding_digest_demo/onboarding_in_app/empty_state/dropdown/onboarding_get_started/bridge/dashboard/ai)=editor, preferences: any, severity: str(high/medium/low/none)}
@returns(201) {data: map{name: str, description: str, tags: [str], active: bool, validatePayload: bool, payloadSchema: map?, isTranslationEnabled: bool, agent: any?, _id: str, workflowId: str, slug: str, updatedAt: str, createdAt: str, updatedBy: any?, lastPublishedAt: str?, lastPublishedBy: any?, steps: [any], origin: str, preferences: any, status: str, issues: map, lastTriggeredAt: str?, payloadExample: map?, severity: str}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint GET /v2/workflows
@optional {limit: num, offset: num, orderDirection: str, orderBy: str, query: str, tags: [str], status: [str]}
@returns(200) {data: map{workflows: [map], totalCount: num}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint PUT /v2/workflows/{workflowId}/sync
@required {workflowId: str, targetEnvironmentId: str}
@returns(200) {data: map{name: str, description: str, tags: [str], active: bool, validatePayload: bool, payloadSchema: map?, isTranslationEnabled: bool, agent: any?, _id: str, workflowId: str, slug: str, updatedAt: str, createdAt: str, updatedBy: any?, lastPublishedAt: str?, lastPublishedBy: any?, steps: [any], origin: str, preferences: any, status: str, issues: map, lastTriggeredAt: str?, payloadExample: map?, severity: str}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint PUT /v2/workflows/{workflowId}
@required {workflowId: str, name: str, steps: [any], preferences: any}
@optional {description: str, tags: [str], active: bool=false, validatePayload: bool, payloadSchema: map, isTranslationEnabled: bool=false, agent: any, workflowId: str, origin: str(novu-cloud/novu-cloud-v1/external), severity: str(high/medium/low/none)}
@returns(200) {data: map{name: str, description: str, tags: [str], active: bool, validatePayload: bool, payloadSchema: map?, isTranslationEnabled: bool, agent: any?, _id: str, workflowId: str, slug: str, updatedAt: str, createdAt: str, updatedBy: any?, lastPublishedAt: str?, lastPublishedBy: any?, steps: [any], origin: str, preferences: any, status: str, issues: map, lastTriggeredAt: str?, payloadExample: map?, severity: str}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint GET /v2/workflows/{workflowId}
@required {workflowId: str}
@optional {environmentId: str}
@returns(200) {data: map{name: str, description: str, tags: [str], active: bool, validatePayload: bool, payloadSchema: map?, isTranslationEnabled: bool, agent: any?, _id: str, workflowId: str, slug: str, updatedAt: str, createdAt: str, updatedBy: any?, lastPublishedAt: str?, lastPublishedBy: any?, steps: [any], origin: str, preferences: any, status: str, issues: map, lastTriggeredAt: str?, payloadExample: map?, severity: str}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint DELETE /v2/workflows/{workflowId}
@required {workflowId: str}
@returns(204)
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint PATCH /v2/workflows/{workflowId}
@required {workflowId: str}
@optional {active: bool, name: str, description: str, tags: [str], payloadSchema: map, validatePayload: bool, isTranslationEnabled: bool}
@returns(200) {data: map{name: str, description: str, tags: [str], active: bool, validatePayload: bool, payloadSchema: map?, isTranslationEnabled: bool, agent: any?, _id: str, workflowId: str, slug: str, updatedAt: str, createdAt: str, updatedBy: any?, lastPublishedAt: str?, lastPublishedBy: any?, steps: [any], origin: str, preferences: any, status: str, issues: map, lastTriggeredAt: str?, payloadExample: map?, severity: str}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint POST /v2/workflows/{workflowId}/step/{stepId}/preview
@required {workflowId: str, stepId: str}
@optional {controlValues: map, previewPayload: any}
@returns(201) {data: map{previewPayloadExample: any, schema: map?, novuSignature: str, result: any}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint GET /v2/workflows/{workflowId}/steps/{stepId}
@required {workflowId: str, stepId: str}
@returns(200) {data: map{controls: any, controlValues: map, providerOverrides: map?, variables: map, stepId: str, _id: str, name: str, slug: str, type: str, origin: str, workflowId: str, workflowDatabaseId: str, issues: any, stepResolverHash: str}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endgroup

@group environments
@endpoint GET /v2/environments/{environmentId}/tags
@required {environmentId: str}
@returns(200) {data: [map]}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint POST /v2/environments/{targetEnvironmentId}/publish
@required {targetEnvironmentId: str}
@optional {sourceEnvironmentId: str, dryRun: bool=false, resources: [map{resourceType!: str, resourceId!: str}]}
@returns(200) {data: map{results: [map], summary: any}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint POST /v2/environments/{targetEnvironmentId}/diff
@required {targetEnvironmentId: str}
@optional {sourceEnvironmentId: str}
@returns(200) {data: map{sourceEnvironmentId: str, targetEnvironmentId: str, resources: [map], summary: any}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endgroup

@group channel-connections
@endpoint GET /v1/channel-connections
@optional {after: str, before: str, limit: num, orderDirection: str(ASC/DESC), orderBy: str, includeCursor: bool, subscriberId: str, connectionMode: str(subscriber/shared), channel: str(in_app/email/sms/chat/push/tool), providerId: str, integrationIdentifier: str, contextKeys: [str]}
@returns(200) {data: map{data: [map], next: str?, previous: str?, totalCount: num, totalCountCapped: bool}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint POST /v1/channel-connections
@required {integrationIdentifier: str, workspace: map{id!: str, name: str, botUserId: str}, auth: map{accessToken!: str, refreshToken: str, expiresAt: str, refreshTokenExpiresAt: str}}
@optional {identifier: str, subscriberId: str, context: map, connectionMode: str(subscriber/shared)}
@returns(201) {data: map{identifier: str, channel: str?, providerId: str?, integrationIdentifier: str?, subscriberId: str?, contextKeys: [str], workspace: map{id: str, name: str, botUserId: str}, auth: map{accessToken: str, refreshToken: str, expiresAt: str, refreshTokenExpiresAt: str}, createdAt: str, updatedAt: str}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint GET /v1/channel-connections/{identifier}
@required {identifier: str}
@returns(200) {data: map{identifier: str, channel: str?, providerId: str?, integrationIdentifier: str?, subscriberId: str?, contextKeys: [str], workspace: map{id: str, name: str, botUserId: str}, auth: map{accessToken: str, refreshToken: str, expiresAt: str, refreshTokenExpiresAt: str}, createdAt: str, updatedAt: str}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint PATCH /v1/channel-connections/{identifier}
@required {identifier: str, workspace: map{id!: str, name: str, botUserId: str}, auth: map{accessToken!: str, refreshToken: str, expiresAt: str, refreshTokenExpiresAt: str}}
@returns(200) {data: map{identifier: str, channel: str?, providerId: str?, integrationIdentifier: str?, subscriberId: str?, contextKeys: [str], workspace: map{id: str, name: str, botUserId: str}, auth: map{accessToken: str, refreshToken: str, expiresAt: str, refreshTokenExpiresAt: str}, createdAt: str, updatedAt: str}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint DELETE /v1/channel-connections/{identifier}
@required {identifier: str}
@returns(204)
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endgroup

@group channel-endpoints
@endpoint GET /v1/channel-endpoints
@optional {after: str, before: str, limit: num, orderDirection: str(ASC/DESC), orderBy: str, includeCursor: bool, subscriberId: str, contextKeys: [str], channel: str(in_app/email/sms/chat/push/tool), providerId: str, integrationIdentifier: str, connectionIdentifier: str}
@returns(200) {data: map{data: [map], next: str?, previous: str?, totalCount: num, totalCountCapped: bool}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint POST /v1/channel-endpoints
@returns(201) {data: map{identifier: str, channel: str?, providerId: str?, integrationIdentifier: str?, connectionIdentifier: str?, subscriberId: str?, contextKeys: [str], type: str, endpoint: any, createdAt: str, updatedAt: str}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint GET /v1/channel-endpoints/{identifier}
@required {identifier: str}
@returns(200) {data: map{identifier: str, channel: str?, providerId: str?, integrationIdentifier: str?, connectionIdentifier: str?, subscriberId: str?, contextKeys: [str], type: str, endpoint: any, createdAt: str, updatedAt: str}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint PATCH /v1/channel-endpoints/{identifier}
@required {identifier: str, endpoint: any}
@returns(200) {data: map{identifier: str, channel: str?, providerId: str?, integrationIdentifier: str?, connectionIdentifier: str?, subscriberId: str?, contextKeys: [str], type: str, endpoint: any, createdAt: str, updatedAt: str}}
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endpoint DELETE /v1/channel-endpoints/{identifier}
@required {identifier: str}
@returns(204)
@errors {400, 401, 403, 404, 405, 409, 413, 414, 415, 422, 429, 500, 503}

@endgroup

@group translations
@endpoint POST /v2/translations/upload
@returns(200) {totalFiles: num, successfulUploads: num, failedUploads: num, errors: [str]}

@endpoint POST /v2/translations
@required {resourceId: str, resourceType: str(workflow/layout), locale: str, content: map}
@returns(200) {resourceId: str, resourceType: str, locale: str, content: map, createdAt: str, updatedAt: str}

@endpoint GET /v2/translations/master-json
@optional {locale: str}
@returns(200) {workflows: map, layouts: map}

@endpoint POST /v2/translations/master-json
@required {locale: str, masterJson: map}
@returns(200) {success: bool, message: str, successful: [str], failed: [str]}

@endpoint POST /v2/translations/master-json/upload
@returns(200) {success: bool, message: str, successful: [str], failed: [str]}

@endpoint GET /v2/translations/group/{resourceType}/{resourceId}
@required {resourceType: str(workflow/layout), resourceId: str}
@returns(200) {resourceId: str, resourceType: str, resourceName: str, locales: [str], outdatedLocales: [str], createdAt: str, updatedAt: str}
@errors {404}

@endpoint GET /v2/translations/{resourceType}/{resourceId}/{locale}
@required {resourceType: str(workflow/layout), resourceId: str, locale: str}
@returns(200) {resourceId: str, resourceType: str, locale: str, content: map, createdAt: str, updatedAt: str}
@errors {404}

@endpoint DELETE /v2/translations/{resourceType}/{resourceId}/{locale}
@required {resourceType: str(workflow/layout), resourceId: str, locale: str}
@returns(204)
@errors {404}

@endpoint DELETE /v2/translations/{resourceType}/{resourceId}
@required {resourceType: str(workflow/layout), resourceId: str}
@returns(204)
@errors {404}

@endgroup

@group inbound-webhooks
@endpoint POST /v2/inbound-webhooks/delivery-providers/{environmentId}/{integrationId}
@required {environmentId: str, integrationId: str}
@returns(200)

@endgroup

@end
