TypeScript SDK
@nodaro/sdk를 설치하고 API 토큰으로 인증한 다음, Node.js, 브라우저, 엣지 런타임에서 TypeScript로 Nodaro 노드와 워크플로를 실행하세요.
Nodaro TypeScript SDK는 Nodaro REST API의 타입 지정 클라이언트이며, npm에 @nodaro/sdk로 게시되어 있습니다. 단일 노드와 워크플로 전체를 실행하고, 결과를 기다리고, 캐릭터, 보이스, 미디어 등을 관리합니다. Node.js, 브라우저, 엣지 런타임에서 동작하며, 모든 API 오류는 처리할 수 있는 타입 지정 오류 클래스로 전달됩니다.
설치
npm install @nodaro/sdk- 이 패키지는 Apache-2.0 라이선스의 오픈 소스입니다. npm의 @nodaro/sdk와 GitHub의 소스를 참조하세요.
- ES 모듈 빌드와 CommonJS 빌드를 TypeScript 타입 정의와 함께 제공합니다.
- Node.js 20 이상이 필요합니다. 최신 브라우저, React Native, Cloudflare Workers, Deno, Bun처럼 전역
fetch와URL이 있는 모든 런타임에서도 실행됩니다. - 다른 Nodaro 패키지 2개를 함께 설치합니다. 전송 타입과 모델 카탈로그를 담은
@nodaro/shared, 프롬프트 헬퍼를 담은@nodaro/prompts입니다. @supabase/supabase-js와@supabase/ssr은 선택적 피어 의존성입니다.supabaseAuth나@nodaro/sdk/supabase를 통해 Supabase로 사용자를 로그인시키는 브라우저 앱에서만 설치하세요.- Nodaro CLI는 이 SDK를 기반으로 만들어졌으므로, CLI 명령과 SDK 호출은 같은 엔드포인트에 도달합니다.
API 토큰 받기
한 번만 복사
토큰은 ndr_로 시작하며 한 번만 표시됩니다. Nodaro는 토큰의 해시만 보관하므로 잃어버린 토큰은 다시 표시할 수 없습니다. 대신 새 토큰을 만드세요.
코드에 넣지 않기
토큰은 NODARO_TOKEN 같은 환경 변수나 시크릿 관리자에 저장하세요. 클라이언트 쪽 코드에는 절대 넣지 마세요.
개인 토큰은 나로서 동작합니다. 많은 사용자가 연결하는 앱처럼 다른 사람을 대신해 동작하려면 OAuth를 사용하세요. 모든 방식은 인증에서 비교합니다.
첫 번째 호출
import { createClient, StaticTokenAuth } from "@nodaro/sdk"
const client = createClient({
baseUrl: "https://app.nodaro.ai",
auth: new StaticTokenAuth(process.env.NODARO_TOKEN!),
})
const { data: nodes } = await client.nodes.list()
console.log(`${nodes.length} node types available`)client.nodes.list()는 비용이 들지 않고 스코프도 필요하지 않으므로, 연결을 처음 테스트하기에 좋습니다. 셀프 호스팅 설치에서는 baseUrl을 내 인스턴스의 주소로 설정하세요. Nodaro와 같은 출처에서 제공되는 브라우저 앱에서는 빈 문자열을 사용하세요. createClient의 모든 옵션은 클라이언트에 나와 있습니다.
이미지를 만든 다음 동영상 만들기
const image = await client.nodes.runAndWait("generate-image", {
prompt: "A snow leopard resting on a rock at sunrise",
provider: "nano-banana-2",
})
console.log(image.imageUrl)
const video = await client.nodes.runAndWait("generate-video", {
prompt: "The snow leopard slowly turns its head toward the camera",
imageUrl: image.imageUrl,
provider: "seedance-2-fast",
duration: 4,
})
console.log(video.videoUrl)runAndWait는 실행을 시작하고, 폴링하고, 작업의 출력으로 이행합니다. 이미지는 imageUrl, 동영상은 videoUrl, 오디오는 audioUrl입니다. 첫 번째 호출은 Nano Banana 2로 이미지 생성 노드를 실행합니다. 두 번째 호출은 Seedance 2 Fast로 동영상 생성 노드를 실행해 그 이미지에 움직임을 줍니다.
노드의 기본 모델을 쓰려면 provider를 빼세요. 각 노드 페이지에 실행할 수 있는 모델과 크레딧 가격이 나와 있으며, 코드에서는 client.models.list()가 같은 카탈로그를 반환합니다. 모델과 크레딧을 참조하세요.
실행 방식
생성은 비동기로 진행됩니다. 요청은 워커에서 작업을 시작하고 바로 반환됩니다. 결과는 몇 초 또는 몇 분 뒤에 도착합니다.
| 호출 | 반환값 | 다음에 할 일 |
|---|---|---|
client.nodes.run(type, params) | { jobId } | 상태가 completed, failed, cancelled 중 하나가 될 때까지 client.jobs.getStatus(jobId)를 폴링하세요. |
client.nodes.runAndWait(type, params, opts) | 작업의 출력 | 할 일이 없습니다. SDK가 최대 15분 동안 2초마다 폴링합니다. |
client.nodes.runMany(type, paramsList, opts) | 요청마다 { jobId, output } 하나 | 할 일이 없습니다. 실행이 함께 시작되고 입력 순서대로 이행합니다. |
client.workflows.run(id) | { executionId, status } | 실행이 끝날 때까지 client.executions.get(executionId)를 폴링하세요. |
텍스트 합치기 같은 몇몇 노드 유형은 인라인으로 실행되어 jobId 없이 결과를 바로 반환합니다. 모든 실행 메서드는 노드 실행에서, 상태는 작업과 실행에서 설명합니다.
진행률 표시와 기다리기 중지
import { JobAbortedError } from "@nodaro/sdk"
const controller = new AbortController()
stopButton.onclick = () => controller.abort()
try {
const clip = await client.nodes.runAndWait(
"generate-video",
{ prompt: "Waves roll onto a black sand beach", provider: "seedance-2-fast", duration: 4 },
{
signal: controller.signal,
onProgress: (status) => setProgressBar(status.progress ?? 0),
},
)
showVideo(clip.videoUrl)
} catch (err) {
if (err instanceof JobAbortedError && err.jobId) {
await client.jobs.cancel(err.jobId)
} else {
throw err
}
}onProgress는 폴링할 때마다 작업 상태를 받으며, 모델이 알려 주는 경우 0~100의 progress가 들어 있습니다. 시그널을 중단하면 기다리기만 멈춥니다. 작업은 client.jobs.cancel(jobId)로 취소할 때까지 계속 실행되며, 취소하면 예약된 크레딧도 환불됩니다.
결과는 도착하는 즉시 하나씩 표시하세요. 2단계 흐름에서는 동영상 단계가 실행되는 동안 이미지를 먼저 보여 주세요.
인증 방식 선택
| 공급자 | 사용 시기 | 토큰 출처 |
|---|---|---|
StaticTokenAuth | 고정 토큰 하나를 쓰는 서버 코드 | API 토큰(ndr_...) 또는 OAuth 액세스 토큰(ndr_app_...) |
CallbackAuth | 토큰을 직접 갱신하거나 교체할 때 | 매 요청 전에 호출되는 내 함수 |
supabaseAuth | 사용자가 같은 Nodaro 인스턴스에 로그인하는 브라우저 앱 | 사용자의 현재 세션 |
모든 요청은 공급자에게 토큰을 요청하고, 그 토큰을 Authorization: Bearer <token>으로 보냅니다. 공급자가 null을 반환하면 요청은 헤더 없이 전송됩니다. 각 공급자와 브라우저 관련 규칙은 인증을 참조하세요.
오류 처리
API가 오류로 응답하면 모든 메서드는 NodaroError의 타입 지정 하위 클래스를 발생시킵니다. 구체적인 클래스를 먼저 처리하고 NodaroError는 마지막에 처리하세요.
import {
InsufficientCreditsError,
NodaroError,
RateLimitedError,
UnauthorizedError,
} from "@nodaro/sdk"
try {
await client.workflows.run(workflowId)
} catch (err) {
if (err instanceof InsufficientCreditsError) {
showPaywall({ required: err.required, available: err.available })
} else if (err instanceof UnauthorizedError) {
askForANewToken()
} else if (err instanceof RateLimitedError) {
retryLater()
} else if (err instanceof NodaroError) {
console.error(`API error ${err.status} (${err.code}): ${err.message}`)
} else {
throw err // a network failure, not an API answer
}
}모든 NodaroError에는 message, insufficient_credits 같은 고정 code, HTTP status가 있습니다. 모든 클래스와 발생 시점은 오류에 나와 있습니다.
자주 쓰는 예제
워크플로를 실행하고 기다리기
client.workflows.run()은 워크플로의 모든 노드를 한 번 실행하는 실행을 시작하고 바로 반환됩니다. 상태가 종료 상태가 될 때까지 client.executions.get()을 폴링하세요.
const { executionId } = await client.workflows.run(workflowId)
for (;;) {
const { data } = await client.executions.get(executionId)
console.log(`${data.completedNodes}/${data.totalNodes} nodes done`)
if (["completed", "failed", "cancelled", "timed_out"].includes(data.status)) {
if (data.status !== "completed") throw new Error(data.errorMessage ?? data.status)
console.log(`Done. Used ${data.totalCreditsUsed} credits.`)
break
}
await new Promise((resolve) => setTimeout(resolve, 2_000))
}일부 노드만 실행하려면 두 번째 인수로 { nodeIds: [...] }를 전달하세요. 워크플로와 프로젝트를 참조하세요.
후보 여러 개를 한 번에 생성하기
const results = await client.nodes.runMany("generate-image", [
{ prompt: "A lighthouse at dawn, watercolor" },
{ prompt: "A lighthouse at dusk, watercolor" },
{ prompt: "A lighthouse in a storm, watercolor" },
])
for (const { jobId, output } of results) console.log(jobId, output.imageUrl)runMany는 실행이 하나라도 실패하면 거부됩니다. 모델이 가장 좋은 결과를 고르게 하려면 URL을 client.reduce.run()에 전달하세요.
이미지는 호출 한 번으로 같은 일을 할 수 있습니다. runBatchAndWait()는 count(이미지 14장) 또는 4개)를 받습니다. 일괄 처리는 전체로 청구되며, 이미지 하나가 실패해도 나머지는 버려지지 않습니다.models(이미지 모델 2
const { results } = await client.nodes.runBatchAndWait("generate-image", {
prompt: "A lighthouse at dusk, watercolor",
count: 4,
})
for (const r of results) if (r.status === "completed") console.log(r.output.imageUrl)파일을 업로드해 사용하기
const upload = await client.uploads.upload(file) // a File, in the browser or Node.js
const portrait = await client.nodes.runAndWait("generate-image", {
prompt: "The same person as a watercolor portrait",
referenceImageUrls: [upload.url],
})업로드는 공개 url을 반환하며, 이 URL은 이미지, 동영상, 오디오 URL을 받는 모든 노드에 전달할 수 있습니다. 미디어와 업로드를 참조하세요.
실행 전에 가격 확인하기
const { total } = await client.credits.balance()
const { data: prices } = await client.credits.modelCosts(["nano-banana-pro", "nano-banana-pro:4K"])
if (total < prices["nano-banana-pro:4K"]) showPaywall()가격과 잔액은 Nodaro Cloud에 있습니다. 모델과 크레딧과 크레딧을 참조하세요.
폴링 대신 작업 완료 알림 받기
https 엔드포인트를 한 번 등록하세요. 그 뒤로 Nodaro는 내 계정의 모든 job.completed와 job.failed에 대해 서명된 POST를 보내며, 서버가 2xx 상태로 응답할 때까지 다시 시도합니다.
const { data: endpoint, secret } = await client.webhooks.create({ url: "https://example.com/nodaro-webhook" })
// `secret` is shown only once: keep it with your server's configuration.
await client.webhooks.test(endpoint.id) // a ping; see client.webhooks.deliveries(endpoint.id)받는 쪽에서는 본문을 신뢰하기 전에 원본 본문의 서명을 확인하세요.
import { verifyWebhookSignature } from "@nodaro/sdk"
const event = await verifyWebhookSignature({
payload: rawBody,
header: request.headers.get("nodaro-signature"),
secret: process.env.NODARO_WEBHOOK_SECRET!,
})
if (event.type === "job.completed") console.info(event.data.job.output_data)이벤트, 본문, 재시도 일정은 client.webhooks와 Webhook을 참조하세요.
생성 전에 프롬프트 다듬기
const { prompt } = await client.promptHelper.enhance({
nodeType: "generate-image",
prompt: "snow leopard on a rock",
})프롬프트 마법사는 대략적인 아이디어를 지정한 노드에 맞는 자세한 프롬프트로 다시 작성합니다. 호출할 때마다 크레딧이 듭니다.
AI 코딩 어시스턴트와 함께 SDK 사용하기
- Claude Code 플러그인.
/plugin marketplace add nodaroai/app.nodaro.ai를 실행한 다음/plugin install nodaro를 실행하세요. 플러그인은 SDK의 패턴, 모델, 크레딧을 아는 스킬을 추가하고, Nodaro의 호스팅 MCP 서버를 연결합니다. 에이전트 스킬을 참조하세요. - 다른 어시스턴트. npm의 패키지 README는 코딩 어시스턴트를 위해 쓴 짧은 입문 내용으로 시작합니다. 이 내용을 요청과 함께 Cursor나 다른 어시스턴트에 붙여 넣으세요.
- 코드 없이. 어시스턴트가 나 대신 Nodaro를 실행하게 하려면 MCP로 연결하세요.
참조
클라이언트
createClient, 모든 옵션, 워크스페이스, 전체 리소스 목록입니다.
인증
StaticTokenAuth, CallbackAuth, supabaseAuth와 공유 브라우저 세션입니다.
오류
모든 오류 클래스, 그 상태와 코드, 복구 방법입니다.
노드 실행
타입이 지정된 매개변수와 함께 쓰는 run, runAndWait, runMany입니다.
워크플로와 프로젝트
워크플로 만들기, 업데이트, 공유, 내보내기, 실행입니다.
작업과 실행
실행 폴링, 목록, 취소, 삭제입니다.
SDK는 REST API와 같은 엔드포인트를 감쌉니다. 아직 SDK 메서드가 없는 엔드포인트는 client.request()로 호출하세요. 같은 인증과 타입 지정 오류가 그대로 유지됩니다.
자주 묻는 질문
@nodaro/sdk는 무엇인가요?
Nodaro REST API의 공식 TypeScript 클라이언트입니다. 노드와 워크플로를 실행하고, 결과를 기다리고, 캐릭터, 보이스, 미디어 등을 관리합니다. 모든 호출에 타입이 지정된 메서드와 타입이 지정된 오류가 있습니다.
Nodaro SDK는 어떻게 인증하나요?
Nodaro의 설정 › API 토큰에서 토큰을 만들고, 환경 변수에 저장한 다음, new StaticTokenAuth(token)으로 createClient에 전달하세요. 브라우저 앱과 OAuth 앱은 대신 supabaseAuth나 CallbackAuth를 사용합니다.
SDK는 어떤 런타임을 지원하나요?
Node.js 20 이상, 그리고 최신 브라우저, React Native, Cloudflare Workers, Deno, Bun처럼 전역 fetch와 URL이 있는 모든 런타임을 지원합니다.
결과를 직접 폴링해야 하나요?
아니요. client.nodes.runAndWait가 실행을 시작하고, 작업을 2초마다 폴링하고, 출력 URL로 이행합니다. 완전히 제어해야 할 때만 client.jobs.getStatus로 직접 루프를 작성하세요.
셀프 호스팅 Nodaro 설치에서도 SDK를 사용할 수 있나요?
네. baseUrl을 내 인스턴스의 주소로 설정하세요. 스튜디오 프로덕션, Recast, 조직 같은 일부 리소스는 Nodaro Cloud에만 있으며, 다른 곳에서는 404로 응답합니다.
관련 문서
클라이언트
인증
노드 실행
오류
REST API 개요
최종 업데이트