Nodaro 문서
문서노드 레퍼런스모델템플릿AI 에이전트(MCP)개발자셀프 호스팅리서치비교
TypeScript SDK

클라이언트

createClient로 Nodaro SDK 클라이언트를 만들고 기본 URL, 인증, 타임아웃, 워크스페이스를 설정하는 방법과 클라이언트가 제공하는 모든 리소스를 안내합니다.

클라이언트는 createClient()가 반환하는 객체입니다. NodaroClient는 내 기본 URL, 인증 공급자, 설정을 보관하고, client.workflows나 client.nodes처럼 Nodaro API의 모든 부분을 리소스로 제공합니다. 클라이언트는 한 번 만들고 모든 호출에서 다시 사용하세요.

클라이언트 만들기

import { createClient, StaticTokenAuth } from "@nodaro/sdk"

const client = createClient({
  baseUrl: "https://app.nodaro.ai",
  auth: new StaticTokenAuth(process.env.NODARO_TOKEN!),
  timeoutMs: 120_000,
})
createClient(options: ClientOptions): NodaroClient

속성

타입

NodaroClient는 클래스로도 내보내지므로, 클라이언트를 받는 함수에 타입을 지정할 수 있습니다.

import type { NodaroClient } from "@nodaro/sdk"

async function countWorkflows(client: NodaroClient, projectId: string) {
  const { data } = await client.workflows.list({ projectId })
  return data.length
}

클라이언트의 리소스

모든 리소스는 createClient가 만들며, client.<resource>로 접근합니다.

리소스다루는 내용참조
client.workflows워크플로: 만들기, 업데이트, 공유, 내보내기, 가져오기, 실행워크플로와 프로젝트
client.projects워크플로를 담는 프로젝트워크플로와 프로젝트
client.sessions프로젝트 안의 생성 세션워크플로와 프로젝트
client.executions워크플로 전체의 실행작업과 실행
client.jobs개별 생성 작업과 그 평가, 필터작업과 실행
client.webhooks작업이 끝날 때 Nodaro가 호출하는 엔드포인트작업과 실행
client.videoPro동영상 생성 Pro 실행 중지 또는 이어 가기작업과 실행
client.nodes노드 카탈로그와 단일 노드 실행노드 실행
client.apps게시된 앱과 그 실행앱과 템플릿
client.templates템플릿 마켓플레이스앱과 템플릿
client.tutorials튜토리얼 동영상과 튜토리얼 워크플로앱과 템플릿
client.llm언어 모델의 구조화된 출력LLM과 Reduce
client.reduce여러 결과 중 가장 좋은 것을 고르거나 하나로 합치기LLM과 Reduce
client.uploads파일 업로드미디어와 업로드
client.library내가 저장한 미디어미디어와 업로드
client.gallery공개 갤러리와 내 즐겨찾기미디어와 업로드
client.media미디어 다운로드, 자르기, 자막, 오버레이, 콜라주미디어와 업로드
client.voices보이스, 보이스 체인저, 보이스 디자인, 더빙보이스와 오디오
client.audio오디오 분리, 추출, 믹스, 자르기, 텍스트 변환보이스와 오디오
client.edit무음 감지, 오디오 동기화, 편집 계획, EDL 렌더링편집
client.scene3d편집 가능한 3D 장면과 3D 렌더링 Pro3D 장면
client.characters캐릭터캐릭터
client.locations장소장소
client.objects오브젝트와 소품오브젝트와 크리처
client.creatures동물과 크리처오브젝트와 크리처
client.community함께 쓰는 커뮤니티 에셋 라이브러리커뮤니티 라이브러리
client.studio스튜디오 프로덕션스튜디오 프로덕션
client.shots공유 링크 뒤에 있는 공유 샷 기록스튜디오 프로덕션
client.recastRecast 실행과 작성된 스크립트Recast
client.pipelines스토리를 동영상으로 만드는 파이프라인파이프라인
client.copilotCopilot 스레드, Nodaro 앱 안에서만 사용Copilot
client.models모델 카탈로그모델과 크레딧
client.credits내 잔액과 모델 가격모델과 크레딧
client.billing요금제, 가격, 내 구독모델과 크레딧
client.pickerCatalogs각 피커에서 쓸 수 있는 옵션피커, 프리셋, 프롬프트
client.catalogs모든 피커 카탈로그를 한 번의 호출로피커, 프리셋, 프롬프트
client.presets저장된 노드 프리셋과 기본 제공 노드 프리셋피커, 프리셋, 프롬프트
client.palettes내 컬러 팔레트피커, 프리셋, 프롬프트
client.moodboards내 무드보드피커, 프리셋, 프롬프트
client.promptHelper프롬프트 마법사피커, 프리셋, 프롬프트
client.organizations조직, 멤버, 초대조직과 워크스페이스
client.workspaces워크스페이스, 멤버, 참여 코드조직과 워크스페이스
client.developerApps내가 소유한 OAuth 앱OAuth와 개발자 앱
client.oauth코드 교환, 토큰 폐기, 동의 화면 데이터OAuth와 개발자 앱

클라이언트 자체에는 메서드가 5개 더 있습니다. me(), connectedApps(), revokeConnectedApp(), withWorkspace(), request()입니다.

메서드가 반환하는 값

  • 엔벨로프는 그대로 유지됩니다. 엔드포인트가 { "data": ... }로 응답하면 메서드는 그 엔벨로프로 이행하므로, const { data } = await client.workflows.get(id)처럼 작성합니다. 페이지 단위 목록에는 nextCursor 같은 커서가 data 옆에 추가됩니다.
  • 일부 리소스는 페이로드를 반환합니다. 몇몇 메서드는 응답을 풀어서 반환합니다. 예를 들어 client.characters.list()는 { characters, nextCursor }로, client.credits.balance()는 잔액 자체로 이행합니다. 정확한 반환 타입은 각 참조 페이지에 나와 있습니다.
  • 삭제와 취소는 보통 { success: true }로 이행합니다.
  • 필드 이름은 전송 형식을 따릅니다. Job은 API가 그렇게 보내므로 output_data나 created_at 같은 snake_case 필드를 사용합니다. Workflow와 WorkflowExecution은 camelCase를 사용합니다.

모든 응답 타입과 입력 타입이 내보내지므로 import type으로 가져올 수 있습니다. 타입을 참조하세요.

me()

me(): Promise<UserIdentity & MeOrganizations>

현재 토큰 뒤에 있는 사용자 정보를 반환합니다(GET /v1/me). 유효한 토큰이면 API 토큰이든 OAuth 액세스 토큰이든 브라우저 세션이든 그 소유자로 이행합니다. 토큰이 없거나 유효하지 않으면 UnauthorizedError가 발생합니다.

const me = await client.me()
console.log(me.email, me.tier)
필드타입설명
idstringNodaro 사용자 ID입니다.
emailstring사용자의 이메일 주소입니다.
displayNamestring | null표시 이름이며, 설정되지 않았으면 null입니다.
avatarUrlstring | null아바타 URL이며, 설정되지 않았으면 null입니다.
tierstring저장된 구독 등급이며, "free"나 "pro" 같은 값입니다. 종량제를 포함해 실제로 적용되는 등급은 client.credits.balance()의 effectiveTier에서 읽으세요.
isAdminboolean사용자가 관리자인지 여부입니다. 무엇을 보여 줄지 정할 때만 사용하세요. 모든 권한은 서버가 직접 확인합니다.

조직이 있는 Nodaro Cloud 인스턴스에서는 결과에 organizations, workspaces, lastWorkspaceId, organizationsUnavailable도 포함됩니다. 세 가지 상태를 각각 다르게 처리하세요.

보이는 것의미할 일
필드가 없음인스턴스에 조직이 없음워크스페이스 전환기를 표시하지 마세요.
필드가 있지만 비어 있음계정이 어떤 조직에도 속하지 않음조직을 만들거나 참여하도록 안내하세요.
organizationsUnavailable: true조회에 실패함이미 선택된 항목을 유지하세요. 사용자에게 접근 권한을 잃었다고 알리지 마세요.

connectedApps()

connectedApps(): Promise<ConnectedApp[]>

로그인한 사용자의 계정에 접근할 수 있는 모든 앱을 최근 권한 부여 순으로 반환합니다(GET /v1/me/connected-apps). 목록에는 개발자 앱, AI 어시스턴트의 MCP 커넥터, 셀프 호스팅 설치가 포함됩니다. 연결된 앱 설정 화면의 데이터입니다. 권한 부여가 무엇인지는 OAuth를 참조하세요.

이 메서드에는 로그인한 브라우저 세션이 필요합니다. supabaseAuth()나 createSharedSupabaseClient의 세션 토큰을 받습니다. API 토큰(ndr_…)이나 앱 토큰(ndr_app_…)은 UnauthorizedError로 거부하므로, 앱은 자신이 쓰는 권한 부여를 나열하거나 취소할 수 없습니다. 서버 측 통합에서는 호출할 수 없습니다.

const apps = await client.connectedApps()
// [{ authorizationId, name, kind, homepageUrl, scopes, connectedAt, lastUsedAt }]
필드타입설명
authorizationIdstring권한 부여입니다. revokeConnectedApp()에 전달하세요.
namestring | null앱의 이름입니다. 스스로 등록한 MCP 클라이언트는 이름을 직접 정했습니다.
kindDeveloperAppKinduser(개발자 앱), first_party_mcp, dynamic_mcp(스스로 등록한 MCP 클라이언트), community_instance(셀프 호스팅 설치) 중 하나입니다.
homepageUrlstring | null앱이 제공한 경우 앱의 홈페이지입니다.
scopesDeveloperAppScope[]권한 부여가 가진 스코프입니다.
connectedAtstring사용자가 접근을 허용한 시각으로, ISO 8601 형식입니다.
lastUsedAtstring | null권한 부여로 발급된 토큰이 가장 최근에 쓰인 시각이며, 한 번도 쓰이지 않았으면 null입니다.

revokeConnectedApp(authorizationId)

revokeConnectedApp(authorizationId: string): Promise<void>

앱의 접근을 끝냅니다(POST /v1/me/connected-apps/:authorizationId/revoke). 권한 부여와 그로 발급된 모든 토큰을 즉시 취소하므로, 앱의 다음 호출은 401로 실패합니다. connectedApps()처럼 로그인한 브라우저 세션이 필요합니다. 권한 부여가 사용자의 것이 아니거나 이미 취소되었으면 NotFoundError를 발생시킵니다.

await client.revokeConnectedApp(app.authorizationId)

withWorkspace(workspaceId)

withWorkspace(workspaceId: string | null): NodaroClient

workspaceId에서 동작하는 새 클라이언트를 반환합니다. 새 클라이언트는 원래 클라이언트의 인증, 기본 URL, 타임아웃, fetch를 공유합니다. 내 개인 공간을 쓰려면 null을 전달하세요.

const classroom = client.withWorkspace(workspaceId)

await classroom.workflows.run(workflowId) // runs in the workspace
await client.workflows.run(workflowId)    // runs in the personal space

이 메서드는 현재 클라이언트를 바꾸지 않고 새 클라이언트를 반환합니다. 따라서 한 클라이언트에서 동시에 실행되는 두 작업의 워크스페이스가 서로 섞일 일이 없습니다.

워크스페이스는 범위를 정할 뿐, 접근 권한은 정하지 않습니다. 목록을 어느 워크스페이스에서 읽을지, 새 항목을 어디에 만들지를 정합니다. ID로 지정한 항목을 읽고, 바꾸고, 삭제하고, 실행할 수 있는지는 그 항목이 속한 워크스페이스에 따라 정해집니다. 워크스페이스를 빠뜨려도 내 작업이 숨겨지지 않고, 잘못 지정해도 다른 사람의 작업에 닿지 않습니다.

워크스페이스는 Nodaro Cloud의 조직에 속합니다. 조직과 워크스페이스와 워크스페이스를 참조하세요.

request(method, path, options)

request<T>(method: string, path: string, options?: {
  body?: unknown
  query?: Record<string, string | number | boolean | undefined>
  headers?: Record<string, string>
  signal?: AbortSignal
}): Promise<T>

모든 엔드포인트에 요청을 보냅니다. 아직 리소스 메서드가 없는 몇몇 엔드포인트에 사용하세요. 인증 헤더와 워크스페이스를 추가하고, body를 JSON으로 보내고, timeoutMs를 적용하며, 리소스 메서드와 같은 타입 지정 오류를 발생시킵니다.

// The same request that client.jobs.list() sends
const page = await client.request<{ data: unknown[]; next: string | null }>("GET", "/v1/jobs", {
  query: { type: "llm-structured", limit: 20 },
})

FormData 본문은 멀티파트 업로드로 전송됩니다. 값이 undefined인 쿼리 항목은 빠집니다. 모든 엔드포인트와 필드는 REST API 참조에 나와 있습니다.

타임아웃과 사용자 지정 fetch

timeoutMs는 제한 시간보다 오래 걸리는 요청을 중단하며, 기본값은 60초입니다. 대부분의 생성은 적당한 HTTP 타임아웃보다 오래 걸리므로, 생성을 시작한 다음 작업을 폴링하세요. client.nodes.runAndWait()가 두 가지를 모두 처리합니다. 스트리밍 메서드인 client.copilot.stream()과 client.media.downloadVideoProgress()는 몇 분 동안 열려 있도록 만들어졌으므로 타임아웃을 적용하지 않습니다.

요청이 전달되는 방식을 바꾸려면 직접 만든 fetch를 전달하세요.

  • 테스트. 목에서 미리 준비한 Response 객체를 반환합니다.
  • 재시도. 전역 fetch를 5xx 응답에서 재시도하는 헬퍼로 감쌉니다.
  • 추적. 사용하는 추적 또는 모니터링 라이브러리로 감쌉니다.
const client = createClient({
  baseUrl: "https://app.nodaro.ai",
  auth: new StaticTokenAuth(process.env.NODARO_TOKEN!),
  fetch: (input, init) => tracedFetch(input, init),
})

런타임과 브라우저

SDK는 fetch와 URL만 사용합니다. 둘 다 Node.js 20 이상, 최신 브라우저, React Native, Cloudflare Workers, Deno, Bun에서 전역으로 제공됩니다. 폴리필은 필요하지 않습니다.

  • OAuth 토큰과 CORS. OAuth 액세스 토큰으로 Nodaro를 호출하는 브라우저 앱은 개발자 앱의 allowedOrigins에 등록된 출처에서 실행되어야 합니다. OAuth와 개발자 앱을 참조하세요.
  • 세션과 CORS. supabaseAuth를 사용하는 브라우저 앱은 이 목록으로 확인하지 않습니다.
  • 클라이언트 레이블. 서버에서는 SDK가 X-Nodaro-Client: sdk/<version>을 보내고, Nodaro는 이 값을 각 작업의 출처로 기록합니다. 브라우저에서는 브라우저의 Origin 헤더가 이미 내 앱을 알려 주므로 기본 레이블을 보내지 않습니다. 직접 설정한 clientLabel은 항상 전송됩니다.

자주 묻는 질문

Nodaro SDK에서는 어떤 기본 URL을 사용해야 하나요?

Nodaro Cloud에서는 https://app.nodaro.ai를 사용하고, 셀프 호스팅 설치에서는 내 인스턴스의 주소를 사용하세요. Nodaro와 같은 출처에서 제공되는 브라우저 앱에서는 빈 문자열을 사용하세요.

기본 요청 타임아웃은 얼마인가요?

60초입니다. timeoutMs 옵션으로 바꿀 수 있습니다. 생성은 어떤 요청보다도 오래 걸리므로, 타임아웃을 늘리는 대신 생성을 시작한 다음 작업을 폴링하세요.

워크스페이스에서 요청을 보내려면 어떻게 하나요?

client.withWorkspace(workspaceId)를 호출하세요. 모든 요청을 그 워크스페이스에서 보내는 새 클라이언트가 반환되며, 원래 클라이언트는 계속 내 개인 공간에서 동작합니다.

SDK 메서드가 없는 엔드포인트는 어떻게 호출하나요?

client.request(method, path, options)를 사용하세요. 다른 모든 리소스 메서드와 같은 인증 헤더를 보내고, 같은 타임아웃을 적용하며, 같은 타입 지정 오류를 발생시킵니다.

최종 업데이트

목차