Layouts
Duplicate a layout
Duplicates a layout by its unique identifier layoutId. This will create a new layout with the content of the original layout.
POST
/
v2
/
layouts
/
{layoutId}
/
duplicate
TypeScript
import { Novu } from "@novu/api";
const novu = new Novu({
secretKey: "YOUR_SECRET_KEY_HERE",
});
async function run() {
const result = await novu.layouts.duplicate({
name: "<value>",
}, "<id>");
console.log(result);
}
run();using Novu;
using Novu.Models.Components;
var sdk = new NovuSDK(secretKey: "YOUR_SECRET_KEY_HERE");
var res = await sdk.Layouts.DuplicateAsync(
layoutId: "<id>",
duplicateLayoutDto: new DuplicateLayoutDto() {
Name = "<value>",
}
);
// 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();
$duplicateLayoutDto = new Components\DuplicateLayoutDto(
name: '<value>',
);
$response = $sdk->layouts->duplicate(
layoutId: '<id>',
duplicateLayoutDto: $duplicateLayoutDto
);
if ($response->layoutResponseDto !== null) {
// handle response
}from novu_py import Novu
with Novu(
secret_key="YOUR_SECRET_KEY_HERE",
) as novu:
res = novu.layouts.duplicate(layout_id="<id>", duplicate_layout_dto={
"name": "<value>",
})
# 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.Layouts.Duplicate(ctx, "<id>", components.DuplicateLayoutDto{
Name: "<value>",
}, nil)
if err != nil {
log.Fatal(err)
}
if res.LayoutResponseDto != nil {
// handle response
}
}curl --request POST \
--url https://api.novu.co/v2/layouts/{layoutId}/duplicate \
--header 'Authorization: <api-key>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "<string>",
"layoutId": "<string>",
"isTranslationEnabled": false
}
'const options = {
method: 'POST',
headers: {Authorization: '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({name: '<string>', layoutId: '<string>', isTranslationEnabled: false})
};
fetch('https://api.novu.co/v2/layouts/{layoutId}/duplicate', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));HttpResponse<String> response = Unirest.post("https://api.novu.co/v2/layouts/{layoutId}/duplicate")
.header("Authorization", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"<string>\",\n \"layoutId\": \"<string>\",\n \"isTranslationEnabled\": false\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.novu.co/v2/layouts/{layoutId}/duplicate")
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\": \"<string>\",\n \"layoutId\": \"<string>\",\n \"isTranslationEnabled\": false\n}"
response = http.request(request)
puts response.read_body{
"_id": "<string>",
"layoutId": "<string>",
"slug": "<string>",
"name": "<string>",
"isDefault": true,
"isTranslationEnabled": true,
"updatedAt": "<string>",
"createdAt": "<string>",
"controls": {
"values": {
"email": {
"body": "<string>"
}
},
"dataSchema": {},
"uiSchema": {
"properties": {}
}
},
"updatedBy": {
"_id": "<string>",
"firstName": "<string>",
"lastName": "<string>",
"externalId": "<string>"
},
"variables": {}
}{
"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",
"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."Authorizations
API key authentication. Allowed headers-- "Authorization: ApiKey <novu_secret_key>".
Headers
A header for idempotency purposes
Path Parameters
Body
application/json
Response
Created
Unique internal identifier of the layout
Unique identifier for the layout
Slug of the layout
Name of the layout
Whether the layout is the default layout
Whether the layout translations are enabled
Last updated timestamp
Creation timestamp
Origin of the layout
Available options:
novu-cloud, novu-cloud-v1, external Type of the layout
Available options:
REGULAR, ECHO, BRIDGE Controls metadata for the layout
Show child attributes
Show child attributes
User who last updated the layout
Show child attributes
Show child attributes
The variables JSON Schema for the layout
Was this page helpful?
⌘I
TypeScript
import { Novu } from "@novu/api";
const novu = new Novu({
secretKey: "YOUR_SECRET_KEY_HERE",
});
async function run() {
const result = await novu.layouts.duplicate({
name: "<value>",
}, "<id>");
console.log(result);
}
run();using Novu;
using Novu.Models.Components;
var sdk = new NovuSDK(secretKey: "YOUR_SECRET_KEY_HERE");
var res = await sdk.Layouts.DuplicateAsync(
layoutId: "<id>",
duplicateLayoutDto: new DuplicateLayoutDto() {
Name = "<value>",
}
);
// 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();
$duplicateLayoutDto = new Components\DuplicateLayoutDto(
name: '<value>',
);
$response = $sdk->layouts->duplicate(
layoutId: '<id>',
duplicateLayoutDto: $duplicateLayoutDto
);
if ($response->layoutResponseDto !== null) {
// handle response
}from novu_py import Novu
with Novu(
secret_key="YOUR_SECRET_KEY_HERE",
) as novu:
res = novu.layouts.duplicate(layout_id="<id>", duplicate_layout_dto={
"name": "<value>",
})
# 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.Layouts.Duplicate(ctx, "<id>", components.DuplicateLayoutDto{
Name: "<value>",
}, nil)
if err != nil {
log.Fatal(err)
}
if res.LayoutResponseDto != nil {
// handle response
}
}curl --request POST \
--url https://api.novu.co/v2/layouts/{layoutId}/duplicate \
--header 'Authorization: <api-key>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "<string>",
"layoutId": "<string>",
"isTranslationEnabled": false
}
'const options = {
method: 'POST',
headers: {Authorization: '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({name: '<string>', layoutId: '<string>', isTranslationEnabled: false})
};
fetch('https://api.novu.co/v2/layouts/{layoutId}/duplicate', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));HttpResponse<String> response = Unirest.post("https://api.novu.co/v2/layouts/{layoutId}/duplicate")
.header("Authorization", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"<string>\",\n \"layoutId\": \"<string>\",\n \"isTranslationEnabled\": false\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.novu.co/v2/layouts/{layoutId}/duplicate")
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\": \"<string>\",\n \"layoutId\": \"<string>\",\n \"isTranslationEnabled\": false\n}"
response = http.request(request)
puts response.read_body{
"_id": "<string>",
"layoutId": "<string>",
"slug": "<string>",
"name": "<string>",
"isDefault": true,
"isTranslationEnabled": true,
"updatedAt": "<string>",
"createdAt": "<string>",
"controls": {
"values": {
"email": {
"body": "<string>"
}
},
"dataSchema": {},
"uiSchema": {
"properties": {}
}
},
"updatedBy": {
"_id": "<string>",
"firstName": "<string>",
"lastName": "<string>",
"externalId": "<string>"
},
"variables": {}
}{
"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",
"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."