Trigger event
Trigger event is the main (and only) way to send notifications to subscribers. The trigger identifier is used to match the particular workflow associated with it. Maximum number of recipients can be 100. Additional information can be passed according the body interface below. To prevent duplicate triggers, you can optionally pass a transactionId in the request body. If the same transactionId is used again, the trigger will be ignored. The retention period depends on your billing tier.
import { Novu } from "@novu/api";
const novu = new Novu({
secretKey: "YOUR_SECRET_KEY_HERE",
});
async function run() {
const result = await novu.trigger({
workflowId: "workflow_identifier",
payload: {
"comment_id": "string",
"post": {
"text": "string",
},
},
bridgeUrl: "https://your-tunnel.novu.co/api/novu",
overrides: {},
to: "SUBSCRIBER_ID",
actor: "<value>",
context: {
"key": "org-acme",
},
});
console.log(result);
}
run();using Novu;
using Novu.Models.Components;
using System.Collections.Generic;
var sdk = new NovuSDK(secretKey: "YOUR_SECRET_KEY_HERE");
var res = await sdk.TriggerAsync(triggerEventRequestDto: new TriggerEventRequestDto() {
WorkflowId = "workflow_identifier",
Payload = new Dictionary<string, object>() {
{ "comment_id", "string" },
{ "post", new Dictionary<string, object>() {
{ "text", "string" },
} },
},
Overrides = new Overrides() {},
To = To.CreateStr(
"SUBSCRIBER_ID"
),
Actor = Actor.CreateStr(
"<value>"
),
Context = new Dictionary<string, TriggerEventRequestDtoContext>() {
{ "key", TriggerEventRequestDtoContext.CreateStr(
"org-acme"
) },
},
});
// handle responsedeclare(strict_types=1);
require 'vendor/autoload.php';
use novu;
use novu\Models\Components;
$sdk = novu\Novu::builder()
->setSecurity(
'YOUR_SECRET_KEY_HERE'
)
->build();
$triggerEventRequestDto = new Components\TriggerEventRequestDto(
workflowId: 'workflow_identifier',
payload: [
'comment_id' => 'string',
'post' => [
'text' => 'string',
],
],
overrides: new Components\Overrides(),
to: 'SUBSCRIBER_ID',
actor: '<value>',
context: [
'key' => 'org-acme',
],
);
$response = $sdk->trigger(
triggerEventRequestDto: $triggerEventRequestDto
);
if ($response->triggerEventResponseDto !== null) {
// handle response
}import novu_py
from novu_py import Novu
with Novu(
secret_key="YOUR_SECRET_KEY_HERE",
) as novu:
res = novu.trigger(trigger_event_request_dto=novu_py.TriggerEventRequestDto(
workflow_id="workflow_identifier",
payload={
"comment_id": "string",
"post": {
"text": "string",
},
},
overrides=novu_py.Overrides(),
to="SUBSCRIBER_ID",
actor="<value>",
context={
"key": "org-acme",
},
))
# Handle response
print(res)package main
import(
"context"
"github.com/novuhq/novu-go/v3"
"github.com/novuhq/novu-go/v3/models/components"
"log"
)
func main() {
ctx := context.Background()
s := v3.New(
v3.WithSecurity("YOUR_SECRET_KEY_HERE"),
)
res, err := s.Trigger(ctx, components.TriggerEventRequestDto{
WorkflowID: "workflow_identifier",
Payload: map[string]any{
"comment_id": "string",
"post": map[string]any{
"text": "string",
},
},
Overrides: &components.Overrides{},
To: components.CreateToStr(
"SUBSCRIBER_ID",
),
Actor: v3.Pointer(components.CreateActorStr(
"<value>",
)),
Context: map[string]components.TriggerEventRequestDtoContext{
"key": components.CreateTriggerEventRequestDtoContextStr(
"org-acme",
),
},
}, nil)
if err != nil {
log.Fatal(err)
}
if res.TriggerEventResponseDto != nil {
// handle response
}
}curl --request POST \
--url https://api.novu.co/v1/events/trigger \
--header 'Authorization: <api-key>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "workflow_identifier",
"to": [
{
"subscriberId": "<string>",
"firstName": "John",
"lastName": "Doe",
"email": "[email protected]",
"phone": "+1234567890",
"avatar": "https://example.com/avatar.jpg",
"locale": "en-US",
"timezone": "America/New_York",
"data": {},
"channels": [
{
"credentials": {
"webhookUrl": "<string>",
"deviceTokens": [
"<string>"
]
},
"integrationIdentifier": "<string>"
}
]
}
],
"payload": {
"comment_id": "string",
"post": {
"text": "string"
}
},
"bridgeUrl": "https://your-tunnel.novu.co/api/novu",
"overrides": {
"steps": {
"email-step": {
"providers": {
"sendgrid": {
"templateId": "1234567890"
}
},
"layoutId": "step-specific-layout"
}
},
"channels": {
"email": {
"layoutId": "promotional-layout-2024"
}
},
"providers": {
"sendgrid": {
"templateId": "1234567890"
}
},
"email": {},
"push": {},
"sms": {},
"chat": {},
"layoutIdentifier": "<string>"
},
"transactionId": "<string>",
"actor": "<string>",
"tenant": "<string>",
"context": {}
}
'const options = {
method: 'POST',
headers: {Authorization: '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: 'workflow_identifier',
to: [
{
subscriberId: '<string>',
firstName: 'John',
lastName: 'Doe',
email: '[email protected]',
phone: '+1234567890',
avatar: 'https://example.com/avatar.jpg',
locale: 'en-US',
timezone: 'America/New_York',
data: {},
channels: [
{
credentials: {webhookUrl: '<string>', deviceTokens: ['<string>']},
integrationIdentifier: '<string>'
}
]
}
],
payload: {comment_id: 'string', post: {text: 'string'}},
bridgeUrl: 'https://your-tunnel.novu.co/api/novu',
overrides: {
steps: {
'email-step': {
providers: {sendgrid: {templateId: '1234567890'}},
layoutId: 'step-specific-layout'
}
},
channels: {email: {layoutId: 'promotional-layout-2024'}},
providers: {sendgrid: {templateId: '1234567890'}},
email: {},
push: {},
sms: {},
chat: {},
layoutIdentifier: '<string>'
},
transactionId: '<string>',
actor: '<string>',
tenant: '<string>',
context: {}
})
};
fetch('https://api.novu.co/v1/events/trigger', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));HttpResponse<String> response = Unirest.post("https://api.novu.co/v1/events/trigger")
.header("Authorization", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"workflow_identifier\",\n \"to\": [\n {\n \"subscriberId\": \"<string>\",\n \"firstName\": \"John\",\n \"lastName\": \"Doe\",\n \"email\": \"[email protected]\",\n \"phone\": \"+1234567890\",\n \"avatar\": \"https://example.com/avatar.jpg\",\n \"locale\": \"en-US\",\n \"timezone\": \"America/New_York\",\n \"data\": {},\n \"channels\": [\n {\n \"credentials\": {\n \"webhookUrl\": \"<string>\",\n \"deviceTokens\": [\n \"<string>\"\n ]\n },\n \"integrationIdentifier\": \"<string>\"\n }\n ]\n }\n ],\n \"payload\": {\n \"comment_id\": \"string\",\n \"post\": {\n \"text\": \"string\"\n }\n },\n \"bridgeUrl\": \"https://your-tunnel.novu.co/api/novu\",\n \"overrides\": {\n \"steps\": {\n \"email-step\": {\n \"providers\": {\n \"sendgrid\": {\n \"templateId\": \"1234567890\"\n }\n },\n \"layoutId\": \"step-specific-layout\"\n }\n },\n \"channels\": {\n \"email\": {\n \"layoutId\": \"promotional-layout-2024\"\n }\n },\n \"providers\": {\n \"sendgrid\": {\n \"templateId\": \"1234567890\"\n }\n },\n \"email\": {},\n \"push\": {},\n \"sms\": {},\n \"chat\": {},\n \"layoutIdentifier\": \"<string>\"\n },\n \"transactionId\": \"<string>\",\n \"actor\": \"<string>\",\n \"tenant\": \"<string>\",\n \"context\": {}\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.novu.co/v1/events/trigger")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"workflow_identifier\",\n \"to\": [\n {\n \"subscriberId\": \"<string>\",\n \"firstName\": \"John\",\n \"lastName\": \"Doe\",\n \"email\": \"[email protected]\",\n \"phone\": \"+1234567890\",\n \"avatar\": \"https://example.com/avatar.jpg\",\n \"locale\": \"en-US\",\n \"timezone\": \"America/New_York\",\n \"data\": {},\n \"channels\": [\n {\n \"credentials\": {\n \"webhookUrl\": \"<string>\",\n \"deviceTokens\": [\n \"<string>\"\n ]\n },\n \"integrationIdentifier\": \"<string>\"\n }\n ]\n }\n ],\n \"payload\": {\n \"comment_id\": \"string\",\n \"post\": {\n \"text\": \"string\"\n }\n },\n \"bridgeUrl\": \"https://your-tunnel.novu.co/api/novu\",\n \"overrides\": {\n \"steps\": {\n \"email-step\": {\n \"providers\": {\n \"sendgrid\": {\n \"templateId\": \"1234567890\"\n }\n },\n \"layoutId\": \"step-specific-layout\"\n }\n },\n \"channels\": {\n \"email\": {\n \"layoutId\": \"promotional-layout-2024\"\n }\n },\n \"providers\": {\n \"sendgrid\": {\n \"templateId\": \"1234567890\"\n }\n },\n \"email\": {},\n \"push\": {},\n \"sms\": {},\n \"chat\": {},\n \"layoutIdentifier\": \"<string>\"\n },\n \"transactionId\": \"<string>\",\n \"actor\": \"<string>\",\n \"tenant\": \"<string>\",\n \"context\": {}\n}"
response = http.request(request)
puts response.read_body{
"acknowledged": true,
"error": [
"<string>"
],
"transactionId": "<string>",
"activityFeedLink": "<string>",
"jobData": {}
}{
"statusCode": 404,
"timestamp": "2024-12-12T13:00:00Z",
"path": "/api/v1/resource",
"type": "PAYLOAD_VALIDATION_ERROR",
"errors": [
{
"field": "user.name",
"message": "must have required property 'name'",
"value": {
"age": 25
},
"schemaPath": "#/required"
}
],
"message": "xx xx xx ",
"ctx": {
"workflowId": "some_wf_id",
"stepId": "some_wf_id"
},
"errorId": "abc123",
"schema": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"age": {
"type": "number"
}
},
"required": [
"name"
]
}
}{
"statusCode": 404,
"timestamp": "2024-12-12T13:00:00Z",
"path": "/api/v1/resource",
"message": "xx xx xx ",
"ctx": {
"workflowId": "some_wf_id",
"stepId": "some_wf_id"
},
"errorId": "abc123"
}{
"statusCode": 404,
"timestamp": "2024-12-12T13:00:00Z",
"path": "/api/v1/resource",
"message": "xx xx xx ",
"ctx": {
"workflowId": "some_wf_id",
"stepId": "some_wf_id"
},
"errorId": "abc123"
}{
"statusCode": 404,
"timestamp": "2024-12-12T13:00:00Z",
"path": "/api/v1/resource",
"message": "xx xx xx ",
"ctx": {
"workflowId": "some_wf_id",
"stepId": "some_wf_id"
},
"errorId": "abc123"
}{
"statusCode": 404,
"timestamp": "2024-12-12T13:00:00Z",
"path": "/api/v1/resource",
"message": "xx xx xx ",
"ctx": {
"workflowId": "some_wf_id",
"stepId": "some_wf_id"
},
"errorId": "abc123"
}{
"statusCode": 404,
"timestamp": "2024-12-12T13:00:00Z",
"path": "/api/v1/resource",
"message": "xx xx xx ",
"ctx": {
"workflowId": "some_wf_id",
"stepId": "some_wf_id"
},
"errorId": "abc123"
}{
"statusCode": 404,
"timestamp": "2024-12-12T13:00:00Z",
"path": "/api/v1/resource",
"message": "xx xx xx ",
"ctx": {
"workflowId": "some_wf_id",
"stepId": "some_wf_id"
},
"errorId": "abc123"
}{
"statusCode": 404,
"timestamp": "2024-12-12T13:00:00Z",
"path": "/api/v1/resource",
"message": "xx xx xx ",
"ctx": {
"workflowId": "some_wf_id",
"stepId": "some_wf_id"
},
"errorId": "abc123"
}{
"statusCode": 404,
"timestamp": "2024-12-12T13:00:00Z",
"path": "/api/v1/resource",
"message": "xx xx xx ",
"ctx": {
"workflowId": "some_wf_id",
"stepId": "some_wf_id"
},
"errorId": "abc123"
}{
"statusCode": 404,
"timestamp": "2024-12-12T13:00:00Z",
"path": "/api/v1/resource",
"errors": {
"fieldName1": {
"messages": [
"Field is required",
"Must be a valid email address"
],
"value": "invalidEmail"
},
"fieldName2": {
"messages": [
"Must be at least 18 years old"
],
"value": 17
},
"fieldName3": {
"messages": [
"Must be a boolean value"
],
"value": true
},
"fieldName4": {
"messages": [
"Must be a valid object"
],
"value": {
"key": "value"
}
},
"fieldName5": {
"messages": [
"Field is missing"
],
"value": null
},
"fieldName6": {
"messages": [
"Undefined value"
]
}
},
"message": "xx xx xx ",
"ctx": {
"workflowId": "some_wf_id",
"stepId": "some_wf_id"
},
"errorId": "abc123"
}"API rate limit exceeded"{
"statusCode": 404,
"timestamp": "2024-12-12T13:00:00Z",
"path": "/api/v1/resource",
"message": "xx xx xx ",
"ctx": {
"workflowId": "some_wf_id",
"stepId": "some_wf_id"
},
"errorId": "abc123"
}"Please wait some time, then try again."POST request with the workflow identifier, target subscriber(s), and optional payload. The response includes a transactionId you can use to trace the run in the Activity Feed, cancel the event, or look up related messages.
Idempotency and billing
If you retry a trigger request, use an idempotency key to avoid duplicate workflow runs and duplicate billing.| Mechanism | Where it applies | Effect on billing |
|---|---|---|
Idempotency-Key header | API layer, before the request is queued | After the first request completes, duplicates return the cached response and count as one workflow run |
transactionId in the request body | During trigger processing | Does not provide the same API-level protection as an idempotency key |
Idempotency-Key on multiple POST /v1/events/trigger requests, Novu halts duplicates at the API layer. Once the first request completes, later requests return the cached response and never reach the worker queue, so only one trigger counts toward billing. While the first request is still processing, duplicates receive a 409 Conflict response.
The optional transactionId field is useful for tracing and cancellation, but it is not a substitute for idempotency. Novu checks transactionId uniqueness during processing rather than at the API boundary, so concurrent or retried requests with the same transactionId are not deduplicated the same way. For safe retries and atomic deduplication, send an Idempotency-Key header on every trigger request.
Authorizations
API key authentication. Allowed headers-- "Authorization: ApiKey <novu_secret_key>".
Headers
A header for idempotency purposes
Body
The trigger identifier of the workflow you wish to send. This identifier can be found on the workflow page.
"workflow_identifier"
The recipients list of people who will receive the notification. Maximum number of recipients can be 100.
Show child attributes
Show child attributes
The payload object is used to pass additional custom information that could be used to render the workflow, or perform routing rules based on it. This data will also be available when fetching the notifications feed from the API to display certain parts of the UI.
{
"comment_id": "string",
"post": { "text": "string" }
}
Optional Bridge Endpoint URL used to route this trigger to a specific Bridge application. Useful during local development when multiple engineers share an organization: set this to your personal tunnel URL from npx novu@latest dev (for example via NOVU_BRIDGE_URL) so app-fired triggers hit your machine instead of the environment's synced Bridge URL. Must be a publicly reachable https URL — private or localhost addresses are rejected.
"https://your-tunnel.novu.co/api/novu"
This could be used to override provider specific configurations
Show child attributes
Show child attributes
A unique identifier for deduplication. If the same transactionId is sent again, the trigger is ignored. Useful to prevent duplicate notifications. The retention period depends on your billing tier.
It is used to display the Avatar of the provided actor's subscriber id or actor object. If a new actor object is provided, we will create a new subscriber in our system
It is used to specify a tenant context during trigger event. Existing tenants will be updated with the provided details.
Show child attributes
Show child attributes
Response
Created
Indicates whether the trigger was acknowledged or not
Status of the trigger
error, trigger_not_active, no_workflow_active_steps_defined, no_workflow_steps_defined, processed, no_tenant_found, invalid_recipients In case of an error, this field will contain the error message(s)
The returned transaction ID of the trigger
Link to the activity feed for this trigger event
Was this page helpful?
import { Novu } from "@novu/api";
const novu = new Novu({
secretKey: "YOUR_SECRET_KEY_HERE",
});
async function run() {
const result = await novu.trigger({
workflowId: "workflow_identifier",
payload: {
"comment_id": "string",
"post": {
"text": "string",
},
},
bridgeUrl: "https://your-tunnel.novu.co/api/novu",
overrides: {},
to: "SUBSCRIBER_ID",
actor: "<value>",
context: {
"key": "org-acme",
},
});
console.log(result);
}
run();using Novu;
using Novu.Models.Components;
using System.Collections.Generic;
var sdk = new NovuSDK(secretKey: "YOUR_SECRET_KEY_HERE");
var res = await sdk.TriggerAsync(triggerEventRequestDto: new TriggerEventRequestDto() {
WorkflowId = "workflow_identifier",
Payload = new Dictionary<string, object>() {
{ "comment_id", "string" },
{ "post", new Dictionary<string, object>() {
{ "text", "string" },
} },
},
Overrides = new Overrides() {},
To = To.CreateStr(
"SUBSCRIBER_ID"
),
Actor = Actor.CreateStr(
"<value>"
),
Context = new Dictionary<string, TriggerEventRequestDtoContext>() {
{ "key", TriggerEventRequestDtoContext.CreateStr(
"org-acme"
) },
},
});
// handle responsedeclare(strict_types=1);
require 'vendor/autoload.php';
use novu;
use novu\Models\Components;
$sdk = novu\Novu::builder()
->setSecurity(
'YOUR_SECRET_KEY_HERE'
)
->build();
$triggerEventRequestDto = new Components\TriggerEventRequestDto(
workflowId: 'workflow_identifier',
payload: [
'comment_id' => 'string',
'post' => [
'text' => 'string',
],
],
overrides: new Components\Overrides(),
to: 'SUBSCRIBER_ID',
actor: '<value>',
context: [
'key' => 'org-acme',
],
);
$response = $sdk->trigger(
triggerEventRequestDto: $triggerEventRequestDto
);
if ($response->triggerEventResponseDto !== null) {
// handle response
}import novu_py
from novu_py import Novu
with Novu(
secret_key="YOUR_SECRET_KEY_HERE",
) as novu:
res = novu.trigger(trigger_event_request_dto=novu_py.TriggerEventRequestDto(
workflow_id="workflow_identifier",
payload={
"comment_id": "string",
"post": {
"text": "string",
},
},
overrides=novu_py.Overrides(),
to="SUBSCRIBER_ID",
actor="<value>",
context={
"key": "org-acme",
},
))
# Handle response
print(res)package main
import(
"context"
"github.com/novuhq/novu-go/v3"
"github.com/novuhq/novu-go/v3/models/components"
"log"
)
func main() {
ctx := context.Background()
s := v3.New(
v3.WithSecurity("YOUR_SECRET_KEY_HERE"),
)
res, err := s.Trigger(ctx, components.TriggerEventRequestDto{
WorkflowID: "workflow_identifier",
Payload: map[string]any{
"comment_id": "string",
"post": map[string]any{
"text": "string",
},
},
Overrides: &components.Overrides{},
To: components.CreateToStr(
"SUBSCRIBER_ID",
),
Actor: v3.Pointer(components.CreateActorStr(
"<value>",
)),
Context: map[string]components.TriggerEventRequestDtoContext{
"key": components.CreateTriggerEventRequestDtoContextStr(
"org-acme",
),
},
}, nil)
if err != nil {
log.Fatal(err)
}
if res.TriggerEventResponseDto != nil {
// handle response
}
}curl --request POST \
--url https://api.novu.co/v1/events/trigger \
--header 'Authorization: <api-key>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "workflow_identifier",
"to": [
{
"subscriberId": "<string>",
"firstName": "John",
"lastName": "Doe",
"email": "[email protected]",
"phone": "+1234567890",
"avatar": "https://example.com/avatar.jpg",
"locale": "en-US",
"timezone": "America/New_York",
"data": {},
"channels": [
{
"credentials": {
"webhookUrl": "<string>",
"deviceTokens": [
"<string>"
]
},
"integrationIdentifier": "<string>"
}
]
}
],
"payload": {
"comment_id": "string",
"post": {
"text": "string"
}
},
"bridgeUrl": "https://your-tunnel.novu.co/api/novu",
"overrides": {
"steps": {
"email-step": {
"providers": {
"sendgrid": {
"templateId": "1234567890"
}
},
"layoutId": "step-specific-layout"
}
},
"channels": {
"email": {
"layoutId": "promotional-layout-2024"
}
},
"providers": {
"sendgrid": {
"templateId": "1234567890"
}
},
"email": {},
"push": {},
"sms": {},
"chat": {},
"layoutIdentifier": "<string>"
},
"transactionId": "<string>",
"actor": "<string>",
"tenant": "<string>",
"context": {}
}
'const options = {
method: 'POST',
headers: {Authorization: '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: 'workflow_identifier',
to: [
{
subscriberId: '<string>',
firstName: 'John',
lastName: 'Doe',
email: '[email protected]',
phone: '+1234567890',
avatar: 'https://example.com/avatar.jpg',
locale: 'en-US',
timezone: 'America/New_York',
data: {},
channels: [
{
credentials: {webhookUrl: '<string>', deviceTokens: ['<string>']},
integrationIdentifier: '<string>'
}
]
}
],
payload: {comment_id: 'string', post: {text: 'string'}},
bridgeUrl: 'https://your-tunnel.novu.co/api/novu',
overrides: {
steps: {
'email-step': {
providers: {sendgrid: {templateId: '1234567890'}},
layoutId: 'step-specific-layout'
}
},
channels: {email: {layoutId: 'promotional-layout-2024'}},
providers: {sendgrid: {templateId: '1234567890'}},
email: {},
push: {},
sms: {},
chat: {},
layoutIdentifier: '<string>'
},
transactionId: '<string>',
actor: '<string>',
tenant: '<string>',
context: {}
})
};
fetch('https://api.novu.co/v1/events/trigger', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));HttpResponse<String> response = Unirest.post("https://api.novu.co/v1/events/trigger")
.header("Authorization", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"workflow_identifier\",\n \"to\": [\n {\n \"subscriberId\": \"<string>\",\n \"firstName\": \"John\",\n \"lastName\": \"Doe\",\n \"email\": \"[email protected]\",\n \"phone\": \"+1234567890\",\n \"avatar\": \"https://example.com/avatar.jpg\",\n \"locale\": \"en-US\",\n \"timezone\": \"America/New_York\",\n \"data\": {},\n \"channels\": [\n {\n \"credentials\": {\n \"webhookUrl\": \"<string>\",\n \"deviceTokens\": [\n \"<string>\"\n ]\n },\n \"integrationIdentifier\": \"<string>\"\n }\n ]\n }\n ],\n \"payload\": {\n \"comment_id\": \"string\",\n \"post\": {\n \"text\": \"string\"\n }\n },\n \"bridgeUrl\": \"https://your-tunnel.novu.co/api/novu\",\n \"overrides\": {\n \"steps\": {\n \"email-step\": {\n \"providers\": {\n \"sendgrid\": {\n \"templateId\": \"1234567890\"\n }\n },\n \"layoutId\": \"step-specific-layout\"\n }\n },\n \"channels\": {\n \"email\": {\n \"layoutId\": \"promotional-layout-2024\"\n }\n },\n \"providers\": {\n \"sendgrid\": {\n \"templateId\": \"1234567890\"\n }\n },\n \"email\": {},\n \"push\": {},\n \"sms\": {},\n \"chat\": {},\n \"layoutIdentifier\": \"<string>\"\n },\n \"transactionId\": \"<string>\",\n \"actor\": \"<string>\",\n \"tenant\": \"<string>\",\n \"context\": {}\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.novu.co/v1/events/trigger")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"workflow_identifier\",\n \"to\": [\n {\n \"subscriberId\": \"<string>\",\n \"firstName\": \"John\",\n \"lastName\": \"Doe\",\n \"email\": \"[email protected]\",\n \"phone\": \"+1234567890\",\n \"avatar\": \"https://example.com/avatar.jpg\",\n \"locale\": \"en-US\",\n \"timezone\": \"America/New_York\",\n \"data\": {},\n \"channels\": [\n {\n \"credentials\": {\n \"webhookUrl\": \"<string>\",\n \"deviceTokens\": [\n \"<string>\"\n ]\n },\n \"integrationIdentifier\": \"<string>\"\n }\n ]\n }\n ],\n \"payload\": {\n \"comment_id\": \"string\",\n \"post\": {\n \"text\": \"string\"\n }\n },\n \"bridgeUrl\": \"https://your-tunnel.novu.co/api/novu\",\n \"overrides\": {\n \"steps\": {\n \"email-step\": {\n \"providers\": {\n \"sendgrid\": {\n \"templateId\": \"1234567890\"\n }\n },\n \"layoutId\": \"step-specific-layout\"\n }\n },\n \"channels\": {\n \"email\": {\n \"layoutId\": \"promotional-layout-2024\"\n }\n },\n \"providers\": {\n \"sendgrid\": {\n \"templateId\": \"1234567890\"\n }\n },\n \"email\": {},\n \"push\": {},\n \"sms\": {},\n \"chat\": {},\n \"layoutIdentifier\": \"<string>\"\n },\n \"transactionId\": \"<string>\",\n \"actor\": \"<string>\",\n \"tenant\": \"<string>\",\n \"context\": {}\n}"
response = http.request(request)
puts response.read_body{
"acknowledged": true,
"error": [
"<string>"
],
"transactionId": "<string>",
"activityFeedLink": "<string>",
"jobData": {}
}{
"statusCode": 404,
"timestamp": "2024-12-12T13:00:00Z",
"path": "/api/v1/resource",
"type": "PAYLOAD_VALIDATION_ERROR",
"errors": [
{
"field": "user.name",
"message": "must have required property 'name'",
"value": {
"age": 25
},
"schemaPath": "#/required"
}
],
"message": "xx xx xx ",
"ctx": {
"workflowId": "some_wf_id",
"stepId": "some_wf_id"
},
"errorId": "abc123",
"schema": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"age": {
"type": "number"
}
},
"required": [
"name"
]
}
}{
"statusCode": 404,
"timestamp": "2024-12-12T13:00:00Z",
"path": "/api/v1/resource",
"message": "xx xx xx ",
"ctx": {
"workflowId": "some_wf_id",
"stepId": "some_wf_id"
},
"errorId": "abc123"
}{
"statusCode": 404,
"timestamp": "2024-12-12T13:00:00Z",
"path": "/api/v1/resource",
"message": "xx xx xx ",
"ctx": {
"workflowId": "some_wf_id",
"stepId": "some_wf_id"
},
"errorId": "abc123"
}{
"statusCode": 404,
"timestamp": "2024-12-12T13:00:00Z",
"path": "/api/v1/resource",
"message": "xx xx xx ",
"ctx": {
"workflowId": "some_wf_id",
"stepId": "some_wf_id"
},
"errorId": "abc123"
}{
"statusCode": 404,
"timestamp": "2024-12-12T13:00:00Z",
"path": "/api/v1/resource",
"message": "xx xx xx ",
"ctx": {
"workflowId": "some_wf_id",
"stepId": "some_wf_id"
},
"errorId": "abc123"
}{
"statusCode": 404,
"timestamp": "2024-12-12T13:00:00Z",
"path": "/api/v1/resource",
"message": "xx xx xx ",
"ctx": {
"workflowId": "some_wf_id",
"stepId": "some_wf_id"
},
"errorId": "abc123"
}{
"statusCode": 404,
"timestamp": "2024-12-12T13:00:00Z",
"path": "/api/v1/resource",
"message": "xx xx xx ",
"ctx": {
"workflowId": "some_wf_id",
"stepId": "some_wf_id"
},
"errorId": "abc123"
}{
"statusCode": 404,
"timestamp": "2024-12-12T13:00:00Z",
"path": "/api/v1/resource",
"message": "xx xx xx ",
"ctx": {
"workflowId": "some_wf_id",
"stepId": "some_wf_id"
},
"errorId": "abc123"
}{
"statusCode": 404,
"timestamp": "2024-12-12T13:00:00Z",
"path": "/api/v1/resource",
"message": "xx xx xx ",
"ctx": {
"workflowId": "some_wf_id",
"stepId": "some_wf_id"
},
"errorId": "abc123"
}{
"statusCode": 404,
"timestamp": "2024-12-12T13:00:00Z",
"path": "/api/v1/resource",
"errors": {
"fieldName1": {
"messages": [
"Field is required",
"Must be a valid email address"
],
"value": "invalidEmail"
},
"fieldName2": {
"messages": [
"Must be at least 18 years old"
],
"value": 17
},
"fieldName3": {
"messages": [
"Must be a boolean value"
],
"value": true
},
"fieldName4": {
"messages": [
"Must be a valid object"
],
"value": {
"key": "value"
}
},
"fieldName5": {
"messages": [
"Field is missing"
],
"value": null
},
"fieldName6": {
"messages": [
"Undefined value"
]
}
},
"message": "xx xx xx ",
"ctx": {
"workflowId": "some_wf_id",
"stepId": "some_wf_id"
},
"errorId": "abc123"
}"API rate limit exceeded"{
"statusCode": 404,
"timestamp": "2024-12-12T13:00:00Z",
"path": "/api/v1/resource",
"message": "xx xx xx ",
"ctx": {
"workflowId": "some_wf_id",
"stepId": "some_wf_id"
},
"errorId": "abc123"
}"Please wait some time, then try again."