프리셋
REST로 내 노드 프리셋을 만들고, 업데이트하고, 가져오고, 순서를 바꾸고, 삭제하세요. 예시 그림이 있는 공개 기본 제공 카탈로그를 읽고, 프리셋 즐겨찾기를 관리합니다.
프리셋 API는 내 노드 프리셋, 그 폴더, 내 즐겨찾기를 읽고 쓰며, 각 노드 타입의 기본 제공 프리셋 카탈로그를 읽습니다. 프리셋은 모델, 프롬프트, 화면 비율, 품질 같은 노드 설정에 이름을 붙인 것으로, 한 번에 노드에 적용할 수 있습니다. 프리셋의 data는 저장된 노드 설정이며, 이를 노드의 data에 병합하면 프리셋이 적용됩니다.
이 라우트는 모든 에디션에서 작동합니다. Bearer 토큰을 받으며, 개인 API 토큰(ndr_…), OAuth 앱 토큰, 또는 세션 토큰을 사용합니다. OAuth 앱 토큰은 읽기에 presets:read, 쓰기에 assets:write가 필요합니다. 기본 제공 카탈로그인 GET /v1/node-presets/factory에는 토큰이 전혀 필요 없습니다. 일부 워크플로로 제한된 개인 토큰은 내 프리셋에 접근할 수 없지만(403 forbidden), 카탈로그는 누구나처럼 읽을 수 있습니다. 인증을 참조하고, 편집기에서 프리셋이 하는 일은 프리셋을 참조하세요.
엔드포인트
| 메서드 | 경로 | 하는 일 |
|---|---|---|
GET | /v1/node-presets | 내 사용자 지정 프리셋으로, 최신순입니다. nodeType 필터는 선택입니다. |
GET | /v1/node-presets/factory | 노드 타입 하나의 기본 제공 카탈로그입니다. nodeType이 필요합니다. 토큰은 필요 없습니다. |
GET | /v1/node-presets/favorites | 노드 타입 하나에서 별표한 프리셋 ID입니다. nodeType이 필요합니다. |
GET | /v1/node-preset-groups | 내 프리셋 폴더와 섹션입니다. nodeType 필터는 선택입니다. |
POST | /v1/node-presets | 프리셋을 만듭니다. |
PATCH | /v1/node-presets/:id | 프리셋의 이름을 바꾸거나, 데이터를 교체하거나, 옮기거나, 그림을 설정합니다. |
DELETE | /v1/node-presets/:id | 프리셋과 그 즐겨찾기 항목을 삭제합니다. |
POST | /v1/node-presets/import | 프리셋을 한 번에 최대 500개까지 만듭니다. |
POST | /v1/node-presets/reorder | 위치를 설정하고, 프리셋을 폴더 사이에서 옮깁니다. |
POST | /v1/node-presets/favorites | 프리셋에 별표합니다. |
DELETE | /v1/node-presets/favorites | 별표를 제거합니다. |
POST | /v1/node-preset-groups | 폴더나 섹션을 만듭니다. |
PATCH | /v1/node-preset-groups/:id | 폴더의 이름을 바꾸거나 옮깁니다. |
DELETE | /v1/node-preset-groups/:id | 폴더를 삭제합니다. 그 안의 프리셋은 폴더 밖으로 옮겨지며, 삭제되지 않습니다. |
내 프리셋 읽기
GET /v1/node-presets는 { data: NodePreset[] }을 최신순으로 반환합니다. 노드 타입 하나의 프리셋을 나열하려면 generate-image 같은 nodeType을 전달하세요.
curl "https://app.nodaro.ai/v1/node-presets?nodeType=generate-image" \
-H "Authorization: Bearer $NODARO_API_KEY"import { createClient, StaticTokenAuth } from '@nodaro/sdk'
const client = createClient({
baseUrl: 'https://app.nodaro.ai',
auth: new StaticTokenAuth(process.env.NODARO_API_KEY!),
})
const presets = await client.presets.list('generate-image')
const cinematic = presets.find((p) => p.name === 'Cinematic Portrait')
const groups = await client.presets.listGroups('generate-image'){
"data": [
{
"id": "7e2c4a9f-1b3d-4f6a-8c5e-2d9b7a1f3c4e",
"nodeType": "generate-image",
"name": "Cinematic Portrait",
"description": "Warm key light, shallow depth of field",
"data": {
"provider": "nano-banana-pro",
"aspectRatio": "3:4",
"resolution": "2K",
"prompt": "cinematic portrait, warm key light, 85mm, shallow depth of field"
},
"groupId": null,
"tags": ["portrait"],
"sortOrder": 0,
"minReferences": 0,
"needsImage": false,
"previewUrl": null,
"createdAt": "2026-09-14T08:12:40Z",
"updatedAt": "2026-09-14T08:12:40Z"
}
]
}| 필드 | 담는 내용 |
|---|---|
id | 프리셋의 uuid입니다. |
nodeType | 프리셋이 속한 노드 타입입니다. |
name, description | 프리셋의 이름과 선택적인 설명입니다. |
data | 저장된 노드 설정입니다. 적용하는 것은 이 값입니다. |
groupId | 프리셋이 들어 있는 폴더(GET /v1/node-preset-groups의 값) 또는 null입니다. |
tags, sortOrder | 내 태그와, 목록 안에서 프리셋의 위치입니다. |
minReferences | 프리셋이 바탕으로 삼는 연결된 레퍼런스 이미지의 수입니다. 0은 없다는 뜻입니다. |
needsImage | minReferences가 1 이상이면 true입니다. |
previewUrl | 내가 준 예시 그림을 프리셋이 따로 보관한 사본, 또는 null입니다. |
createdAt, updatedAt | 타임스탬프입니다. 쓰기에서는 updatedAt을 expectedUpdatedAt으로 다시 보내세요. |
프리셋이 바탕으로 삼는 사진
minReferences가 0보다 큰 프리셋은 그 수만큼 레퍼런스 이미지를 붙여 실행하세요. 이미지가 없으면 프리셋의 프롬프트가 존재하지 않는 사진을 묘사하게 됩니다. POST /v1/generate-image에서 presetId를 쓸 때는 이미지를 referenceImageUrls로 보내세요.
레퍼런스 시트, 출연진 및 일관성, 이름으로 편집, 얼굴 프라이버시, 편집, 인물 사진 변신, 스타일화된 피사체 프리셋은 이미지 1장이 필요하고, 출연진 메가 그리드는 2장이 필요합니다. 프롬프트에 {image:N} 토큰을 쓰는 모든 템플릿도 마찬가지이며, 필요한 수는 가장 큰 N입니다. 내 프리셋도 프롬프트, 앞뒤 텍스트, 네거티브 프롬프트에 있는 {image:N}과 {image:N:label} 토큰으로 같은 방식으로 셉니다.
기본 제공 카탈로그 읽기
GET /v1/node-presets/factory?nodeType=generate-image는 해당 노드 타입에 Nodaro와 함께 제공되는 프리셋인 { data: [...] }을 반환합니다. 각 항목은 { id, name, description?, group?, groupKind?, data, minReferences, needsImage, previewUrl }입니다. 기본 제공 ID의 형식은 <node-type>/<name>이며, 예를 들어 generate-image/character-board나 generate-video/orbit-360입니다.
카탈로그에는 토큰이 필요 없습니다. 누구에게나 같고 사용자 데이터가 없으므로, 클라이언트 앱은 로그인하지 않은 방문자에게도 카탈로그를 보여 주고, 생성할 때만 로그인을 요청할 수 있습니다. 응답은 Cache-Control: public, max-age=300과 함께 전송되며, 요청에 함께 보낸 잘못되었거나 만료된 토큰은 무시됩니다.
기본 제공 프리셋의 previewUrl은 요청한 서버에 있는 예시 그림으로, https://<host>/preset-previews/<nodeType>/<slug>.<hash>.webp 형식이며, 프리셋에 그림이 없는 동안에는 null입니다. 그림이 바뀔 때마다 파일 이름도 바뀌므로, URL을 영구히 캐시해도 됩니다.
# The presets that need a photo, and their example pictures. No token needed.
curl -s "https://app.nodaro.ai/v1/node-presets/factory?nodeType=generate-image" \
| jq '.data[] | select(.needsImage) | {id, minReferences, previewUrl}'const { data } = await client.presets.listFactory('generate-video')
const orbit = data.find((p) => p.id === 'generate-video/orbit-360')프리셋 적용
프리셋으로 이미지 한 장을 생성하려면 POST /v1/generate-image에 그 ID를 presetId로 보내세요. 서버는 편집기가 이미지 생성 노드에 적용하는 방식으로 프리셋을 적용하며, 내가 보낸 필드가 프리셋보다 우선합니다. 이미지 생성에 프리셋 적용을 참조하세요.
워크플로에서 프리셋을 적용하려면 워크플로를 만들거나 업데이트할 때 그 data를 노드의 data에 병합하세요. 병합 후 노드에 설정한 값이 우선합니다.
const node = {
id: 'portrait-1',
type: 'generate-image',
data: { ...cinematic.data, prompt: 'a lighthouse keeper at dawn' },
}프리셋에는 promptPrefix와 promptSuffix도 담길 수 있습니다. 노드가 실행될 때 프롬프트 앞뒤에 추가되는 텍스트입니다. 프롬프트 앞뒤 텍스트를 참조하세요.
MCP에서는 list_node_presets로 프리셋을 찾고 get_node_preset으로 읽거나, generate_image 같은 생성 도구에 presetId를 바로 전달하세요. 그러면 서버가 프리셋을 적용하고, 프리셋의 앞 텍스트와 뒤 텍스트로 내 프롬프트를 감쌉니다. 내가 명시적으로 전달한 필드는 프리셋보다 우선합니다. MCP 도구 레퍼런스를 참조하세요.
즐겨찾기
즐겨찾기는 별표한 프리셋을 편집기 프리셋 목록의 맨 위에 놓습니다. 즐겨찾기 ID는 기본 제공 프리셋 ID이거나 사용자 지정 프리셋의 uuid입니다. OAuth 앱 토큰은 읽기에 presets:read, 쓰기에 assets:write가 필요합니다.
| 메서드 | 경로 | 쿼리 또는 본문 | 반환 |
|---|---|---|---|
GET | /v1/node-presets/favorites | nodeType(필수) | { data: string[] }, 최신순 |
POST | /v1/node-presets/favorites | 본문 { nodeType, presetId } | { data: { success: true } }. 같은 즐겨찾기를 두 번 추가해도 아무것도 바뀌지 않습니다. |
DELETE | /v1/node-presets/favorites | nodeType과 presetId(둘 다 필수) | { data: { success: true } }. 같은 즐겨찾기를 두 번 제거해도 아무것도 바뀌지 않습니다. |
기본 제공 ID에는 /가 들어 있으므로, DELETE 쿼리 문자열에서는 presetId를 URL 인코딩하세요.
curl -X DELETE "https://app.nodaro.ai/v1/node-presets/favorites?nodeType=generate-image&presetId=generate-image%2Fcharacter-board" \
-H "Authorization: Bearer $NODARO_API_KEY"프리셋 만들기와 편집
| 메서드 | 경로 | 본문 또는 쿼리 | 하는 일 |
|---|---|---|---|
POST | /v1/node-presets | { nodeType, name, description?, data, groupId?, tags?, sortOrder?, previewUrl? } | 프리셋을 만듭니다. 프리셋과 함께 201로 응답합니다. |
PATCH | /v1/node-presets/:id | name, description, data, groupId, tags, sortOrder, previewUrl 중 아무것이나, 그리고 선택 사항인 expectedUpdatedAt | 보낸 필드를 업데이트합니다. previewUrl: null은 그림을 제거합니다. |
DELETE | /v1/node-presets/:id | 선택 사항인 expectedUpdatedAt 쿼리 매개변수 | 프리셋과 그 즐겨찾기 항목을 삭제합니다. |
POST | /v1/node-presets/import | { presets: [{ nodeType, name, description?, data, previewUrl? }] }, 최대 500개 | 한 번에 여러 개를 만듭니다. { data: { imported } }를 반환합니다. |
POST | /v1/node-presets/reorder | { groups?: [{ id, sortOrder }], presets?: [{ id, groupId?, sortOrder }] } | 위치를 설정하고 프리셋을 폴더 사이에서 옮깁니다. { data: { ok: true } }를 반환합니다. |
POST | /v1/node-preset-groups | { nodeType, name, kind?, sortOrder? } | folder(기본값, 접을 수 있음) 또는 section(평평한 머리글)을 만듭니다. |
PATCH | /v1/node-preset-groups/:id | { name?, sortOrder? } | 폴더의 이름을 바꾸거나 옮깁니다. |
DELETE | /v1/node-preset-groups/:id | 없음 | 폴더를 삭제합니다. 그 안의 프리셋은 폴더 밖으로 옮겨집니다. |
# Save a preset of your own, with one of your images as its picture
curl -s -X POST "https://app.nodaro.ai/v1/node-presets" \
-H "Authorization: Bearer $NODARO_API_KEY" \
-H "Content-Type: application/json" \
-d '{"nodeType": "generate-image", "name": "Studio portrait", "data": {"provider": "gpt-image-2", "aspectRatio": "3:4", "prompt": "{image:1:person}, studio portrait, soft key light"}, "previewUrl": "https://cdn.nodaro.ai/images/<jobId>.png"}'
# Rename it, refusing if it changed since you read it
curl -s -X PATCH "https://app.nodaro.ai/v1/node-presets/<presetId>" \
-H "Authorization: Bearer $NODARO_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name": "Studio portrait (warm)", "expectedUpdatedAt": "<updatedAt>"}'const preset = await client.presets.create({
nodeType: 'generate-image',
name: 'Studio portrait',
data: { provider: 'gpt-image-2', aspectRatio: '3:4', prompt: '{image:1:person}, studio portrait' },
})
preset.needsImage // true: the prompt names {image:1}
await client.presets.addFavorite({ nodeType: 'generate-image', presetId: preset.id })CLI에도 같은 쓰기 기능이 있습니다: nodaro presets create, update, delete, import, export, favorites, favorite, unfavorite, 그리고 create, update, delete가 있는 nodaro presets groups. MCP에서는 save_node_preset, delete_node_preset, favorite_node_preset으로 프리셋을 관리합니다.
쓰기 규칙
- 이름은 노드 타입마다 고유하며, 대소문자는 구분하지 않습니다. 만들기와 업데이트는
409 name_taken으로 응답합니다. 가져오기는 두 프리셋을 모두 유지하고 새로 온 프리셋에 “… (imported 2)” 같은 이름을 붙입니다. data는 최대 64KB입니다. 결과, 작업 ID, 노드의 레이블 같은 런타임 키는 제거됩니다. 남는 것이 없는 가져온 프리셋은 건너뜁니다.groupId는 내 폴더 중 하나여야 하며, 그렇지 않으면 쓰기가400 invalid_group으로 응답합니다.previewUrl은 Nodaro에 있는 내 이미지여야 합니다. png, jpg, webp, gif, avif 형식의 업로드 또는 완료된 생성 결과입니다. 파일이 이미 있어야 하므로, 그림을 만드는 작업이 완료된 뒤에 설정하세요. 그 밖의 값은 필드 이름을 담은400 validation_error로 응답합니다. 예를 들어 가져오기에서는presets[3].previewUrl입니다.- 프리셋은 그림의 사본을 따로 보관합니다. 응답의
previewUrl은 내가 보낸 주소가 아니라 사본의 주소이므로, 원본을 라이브러리에서 삭제해도 프리셋이 깨지지 않습니다. expectedUpdatedAt을 보내면, 읽은 뒤 프리셋이 변경되었을 때 업데이트나 삭제가409 conflict로 응답합니다. 다시 시도하기 전에 프리셋을 다시 읽으세요.- 내 것이 아닌 프리셋이나 폴더, 또는 uuid가 아닌 ID는
404 not_found로 응답합니다. - 계정마다 프리셋은 최대 5,000개, 폴더는 500개, 즐겨찾기는 2,000개까지 보관합니다. 이를 넘으면 만들기, 가져오기, 즐겨찾기가
409 limit_reached로 응답하며 아무것도 쓰지 않습니다. 전부 들어가지 않는 가져오기는 하나도 가져오지 않습니다. - API 키나 OAuth 앱에서 한 번의 순서 변경으로 옮길 수 있는 것은 프리셋 최대 500개와 폴더 100개입니다. 그보다 많으면
400 validation_error로 응답하므로, 나머지는 다른 호출로 보내세요. - 쓰기는 자격 증명마다 분당 60회, 가져오기는 분당 10회로 제한됩니다. 이를 넘으면 라우트가
429 rate_limit_exceeded로 응답합니다.
Recast 렌더 프리셋
같은 라이브러리에 Recast 생성 설정이 recast-render 네임스페이스로 저장됩니다. 이는 노드 타입이 아니며, Recast 렌더 설정 전체를 저장해 다시 사용할 수 있게 합니다. 기본 제공 항목은 읽기 전용이며, 내 항목은 모든 기기에서 나만 볼 수 있습니다.
recast-render 프리셋의 data는 엄격하고 완전한 스냅샷입니다.
{
"schemaVersion": 1,
"provider": "seedance-2-5",
"resolution": "480p",
"segmentSec": "max",
"renderMethod": "extend",
"anchorMode": "upfront",
"citeStyle": "bare",
"promptTiming": true,
"textOnly": false,
"interactive": true,
"anchorGates": false,
"musicGates": true,
"musicSource": "generated"
}| 필드 | 허용되는 값 |
|---|---|
segmentSec | max, scenes-max(길게) 또는 scenes(짧게)입니다. |
resolution | 480p, 720p, 1080p 또는 4k입니다. |
renderMethod | extend 또는 keyframes입니다. |
anchorMode | upfront, progressive 또는 none입니다. |
citeStyle | bare 또는 rich입니다. |
musicSource | generated, original 또는 upload입니다. |
promptTiming, textOnly, interactive, anchorGates, musicGates | true 또는 false입니다. |
다른 프리셋과 같은 라우트로 씁니다. 사진이 필요 없고 그림도 없습니다(minReferences: 0, previewUrl: null). 알 수 없는 필드와 알 수 없는 스키마 버전은 만들기, 업데이트, 가져오기에서 거부됩니다. 스냅샷에는 원본 미디어, 출연진 레퍼런스, 프롬프트, 업로드한 트랙, 권리 확인, 결과가 절대 들어 있지 않습니다. 프리셋을 적용하면 설정이 바뀌고 가격 견적이 새로 고쳐지지만, 생성이 시작되지는 않습니다. 원본 또는 업로드 음악 선택은 대상 프로젝트 자체의 미디어를 사용합니다. 생성하기 전에 선택한 모델의 현재 기능을 확인하세요.
오류
| 상태 | 코드 | 의미 |
|---|---|---|
400 | validation_error | 필요한 곳에 nodeType이 없거나 필드가 잘못되었습니다. |
400 | invalid_group | groupId가 내 폴더가 아닙니다. |
401 | unauthorized | 토큰이 없거나, 잘못되었거나, 폐기되었습니다. |
403 | forbidden | 일부 워크플로로 제한된 개인 토큰이 내 프리셋을 요청했습니다. |
403 | insufficient_scope | OAuth 앱 토큰에 읽기용 presets:read 또는 쓰기용 assets:write가 없습니다. |
404 | not_found | 프리셋이나 폴더가 내 것이 아니거나, ID가 uuid가 아닙니다. |
409 | name_taken | 이 노드 타입에 같은 이름의 프리셋이 이미 있습니다. |
409 | conflict | expectedUpdatedAt 이후 프리셋이 변경되었습니다. 다시 읽으세요. |
409 | limit_reached | 계정이 프리셋, 폴더, 즐겨찾기 한도에 도달했습니다. |
429 | rate_limit_exceeded | 분당 쓰기 60회 또는 분당 가져오기 10회를 넘었습니다. |
자주 묻는 질문
API 토큰으로 프리셋을 만들거나 편집할 수 있나요?
네. 개인 API 토큰이나 assets:write 스코프가 있는 OAuth 앱 토큰으로 프리셋을 만들고, 업데이트하고, 삭제하고, 가져오고, 순서를 바꾸고, 폴더와 즐겨찾기를 관리할 수 있습니다.
기본 제공 프리셋 카탈로그를 읽으려면 토큰이 필요한가요?
아니요. GET /v1/node-presets/factory는 공개되어 있습니다. 사용자 데이터가 없으므로, 앱은 로그인하지 않은 방문자에게도 예시 그림과 함께 카탈로그를 보여 줄 수 있습니다.
코드에서 프리셋을 적용하려면 어떻게 하나요?
POST /v1/generate-image에 presetId를 보내면 서버가 편집기와 같은 방식으로 프리셋을 적용합니다. 워크플로에서는 프리셋의 data 객체를 노드의 data에 병합하세요.
프리셋의 minReferences는 무슨 뜻인가요?
minReferences는 프리셋이 바탕으로 삼는 연결된 레퍼런스 이미지의 수이며, 그 수가 1 이상이면 needsImage가 true입니다. 이런 프리셋은 그 수만큼 레퍼런스 이미지를 붙여 실행하세요.
프리셋 라우트에는 어떤 OAuth 스코프가 필요한가요?
내 프리셋 읽기에는 presets:read가, 쓰기에는 assets:write가 필요합니다. 기본 제공 카탈로그에는 스코프가 필요 없습니다. 개인 API 토큰과 세션 토큰에는 스코프가 필요 없습니다.
관련 문서
프리셋
프롬프트 앞뒤 텍스트
노드
Recast
MCP 도구 레퍼런스
최종 업데이트