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

모델 및 크레딧

Nodaro 인스턴스가 제공하는 AI 모델을 나열하고, 내 크레딧 잔액을 확인하고, 실행 전에 모델 가격을 조회하고, 요금제와 내 구독을 읽는 방법을 안내합니다.

client.models는 Nodaro 인스턴스가 제공하는 AI 모델 카탈로그를 반환하고, client.credits는 내 크레딧 잔액과 모든 모델의 가격을 반환합니다. client.billing은 판매 중인 요금제와 내 구독을 반환합니다. 이들을 함께 사용해 사용자가 고를 수 있는 모델과 실행마다 드는 비용을 보여 주세요. 이 메서드들은 크레딧 REST API와 같은 엔드포인트를 호출합니다. 가격과 잔액은 Nodaro Cloud에만 있으며, 셀프 호스팅한 Community Edition과 Business 에디션 설치에는 크레딧 시스템이 없습니다. 크레딧을 참고하세요.

메서드

메서드기능
models.list(opts?)모델을 종류와 제작사별로 묶어 나열합니다
credits.balance()내 크레딧 잔액과 등급을 읽어 옵니다
credits.modelCosts(ids)모델 또는 베리언트 최대 50개의 크레딧 가격을 조회합니다
credits.transactions(options?)내 크레딧 거래 내역을 한 페이지씩 읽어 옵니다
credits.claimWelcomeOffer(input?)자사 웹 앱에서 환영 혜택을 수락합니다
credits.markWelcomeOfferSeen()환영 팝업이 표시되었음을 기록합니다
billing.plans() 외판매 중인 요금제와 크레딧 팩, 내 구독, 배포 환경의 결제 방식을 읽어 옵니다

client.models

models.list(opts?)

모델 카탈로그를 종류(이미지, 동영상, 오디오)와 제작사별로 묶어 반환합니다(GET /v1/models). 각 모델에는 기능, Nodaro Cloud에서의 크레딧 가격, 짧은 프롬프트 팁이 있습니다. 이 엔드포인트는 공개되어 있으며, 서버는 응답을 5분 동안 캐시합니다. MCP list_models 도구도 같은 데이터를 반환합니다.

list(opts?: {
  kind?: "image" | "video" | "audio"
  mode?: string
  family?: string
  featuredOnly?: boolean
}): Promise<ModelsListResult>

속성

타입

const catalog = await client.models.list({ kind: "video", mode: "i2v" })

for (const section of catalog.sections) {
  for (const family of section.families) {
    for (const model of family.models) {
      console.log(family.family, model.id, model.durations, model.pricing?.[0]?.credits)
    }
  }
}

결과에는 종류마다 하나씩 있으며 각각 모델의 families를 담은 sections, 자주 쓰는 용도별 모델 ID 목록인 recommendations, 그리고 totalModels가 있습니다. 각 모델에는 다음 필드가 있습니다.

필드타입설명
idstring모델 ID로, 노드 실행의 provider 매개변수에 씁니다.
label, descriptionstring표시 이름과 짧은 설명입니다.
modesstring[]t2i, i2i, t2v, i2v처럼 모델이 하는 일입니다.
useCasesstring[]모델에 맞는 용도입니다.
aspectRatios, resolutions, qualities, durations배열해당하는 경우, 모델이 받는 값입니다.
featuresstring[]추가 기능입니다.
pricing{ identifier, credits, note? }[]각 베리언트의 크레딧 가격입니다. 실행에 청구되는 가격으로, 실행 버튼의 금액과 같습니다. Nodaro Cloud 전용입니다.
featuredboolean추천 모델인지 여부입니다.
promptTipsstring[]모델에 맞는 짧은 프롬프트 작성 조언입니다.
doctrineCoveredbooleanNodaro가 모델 계열의 프롬프트 가이드를 출처와 함께 갖춘 경우에만 true입니다. “제작사 가이드” 배지는 이 값이 true일 때만 표시하세요.
maker{ id, name }모델을 만든 회사입니다. id는 회사마다 하나인 안정적인 값으로, "google"이나 "black-forest-labs" 같은 것이므로 내 에셋의 키로 쓸 수 있습니다. 새 서버는 제작사를 추가할 수 있으므로, 모르는 ID도 처리하세요. 제작사가 모델이 묶인 family와 항상 같지는 않습니다.
logoUrlstring | null제작사의 공식 로고로, 인스턴스 자체 미디어 CDN의 SVG입니다. 인스턴스가 그 제작사의 로고를 게시하지 않으면 null이므로, 대신 제작사의 이름이나 첫 글자를 그리세요. 로고가 바뀌면 새 주소로 오므로 주소를 받은 그대로 쓰세요. MCP 도구는 이 필드를 생략합니다.

오래된 서버는 maker와 logoUrl을 생략합니다.

for (const section of catalog.sections)
  for (const family of section.families)
    for (const m of family.models)
      console.log(m.id, m.maker?.name ?? family.family, m.logoUrl ?? "(no mark)")

같은 카탈로그가 모델 페이지에도 있습니다. 어떤 모델을 쓸지에 대한 조언은 모델 선택을 읽어 보세요.

client.credits

credits.balance()

내 크레딧 잔액과 등급을 반환합니다(GET /v1/user/credits). 로그인한 사용자가 없으면 UnauthorizedError를 발생시킵니다.

balance(): Promise<UserBalance>
const balance = await client.credits.balance()
console.log(`${balance.total} credits (${balance.effectiveTier})`)
필드타입설명
totalnumber지금 사용할 수 있는 크레딧입니다.
subscriptionnumber이번 달에 남은 구독 크레딧입니다. 연간 요금제에서도 매달 monthlyAllocation으로 초기화되며, 쓰지 않은 크레딧은 이월되지 않습니다.
topupnumber따로 구매한 크레딧입니다.
dailySpentnumber오늘 사용한 크레딧입니다.
dailyLimitnumber | null일일 사용 한도이며, 한도가 없으면 null입니다.
monthlyAllocationnumber월간 결제와 연간 결제 모두에서 요금제가 매달 지급하는 크레딧입니다.
tierstring"free"나 "pro"처럼 저장된 구독 등급입니다.
effectiveTierstring실제로 적용되는 등급입니다. "payg"는 종량제를 뜻합니다. 구독은 없지만 구매한 크레딧이 있으며, 모든 모델을 쓸 수 있고 워터마크와 일일 한도가 없습니다.
featuresRecord<string, unknown>등급의 기능입니다.
periodEndstring | null현재 결제 기간이 끝나는 날짜로, ISO 8601 날짜입니다. 연간 요금제에서는 1년 뒤이지만, 구독 크레딧은 여전히 매달 초기화됩니다.
appCreditsAllowancenumber무료 등급에서 앱을 실행해 얻은 크레딧입니다.
freeGrantStateFreeGrantState가입 무료 지급의 상태로, "unclaimed", "granted", "withheld", "revoked" 중 하나입니다. "withheld"는 계정은 작동하지만 지급이 이루어지지 않았다는 뜻이므로 활성화 방법을 보여 주세요. 배포 환경에 가입 지급이 없으면 없습니다.
freeGrantNotice"browser_unmeasured""withheld"일 때만 있으며, 지급 요청에서 브라우저 신호가 전혀 보이지 않았을 때입니다. 앱에서 무료 크레딧을 받으려면 일반 브라우저와 새로고침이 필요하다고 안내할 수 있습니다.
welcomeOfferWelcomeOfferState배포 환경에서 환영 혜택이 켜져 있는 동안에만 있습니다. 없으면 팝업, 배너, 차단이 없다는 뜻입니다. claimWelcomeOffer()를 참고하세요.
externalWallet{ available: number | null }배포가 공유 외부 지갑을 쓸 때 있습니다. null은 금액을 알 수 없다는 뜻입니다. 그 자리에 total을 표시하지 마세요. 외부 지갑을 참고하세요.

무엇을 표시할지 정할 때는 tier보다 effectiveTier를 우선하세요.

credits.modelCosts(ids)

모델과 그 베리언트의 크레딧 가격을 한 번의 호출로 조회합니다(POST /v1/credits/model-costs). 앞에서부터 최대 50개의 식별자를 확인합니다.

modelCosts(ids: string[]): Promise<{
  data: Record<string, number>
  missing: string[]
  errors: string[]
}>

속성

타입

const { data, missing } = await client.credits.modelCosts([
  "nano-banana-pro",
  "nano-banana-pro:4K",
  "seedance-2-fast:8s:720p",
])
console.log(data["nano-banana-pro:4K"])
if (missing.length) console.warn("No price for:", missing)
  • data는 가격이 있는 각 식별자를 크레딧 가격에 대응시킵니다.
  • missing은 가격이 없는 식별자를 나열합니다. 이런 식별자에는 대시를 표시하세요.
  • errors는 조회에 실패한 식별자를 나열합니다. 나머지 가격은 그대로 전달됩니다.

각 모델의 식별자는 models.list()의 pricing 필드와 각 모델 페이지에 있습니다. 품질, 해상도, 길이 같은 설정이 가격을 바꾸므로, 실행에 쓸 베리언트를 지정하세요. 실행 시점의 가격은 실행이 시작될 때 다시 확인되므로, 이 호출은 미리 보기입니다.

음성 모델은 텍스트 길이에 따라 가격이 정해집니다. 시작된 100자 블록마다의 식별자는 <model>:per-100-chars입니다. 예: elevenlabs-v4:per-100-chars. 음성을 길이로 가격 매기지 않는 설치에서는 이 식별자가 missing에 들어가므로, 응답으로 서버가 어떤 규칙으로 청구하는지도 알 수 있습니다.

요청은 전체로 가격을 계산한 뒤 한 번만 반올림합니다. 따라서 시작된 블록이 N개인 요청의 정확한 가격은 식별자 <model>:per-100-chars:<N>u이며, N은 8부터 모델의 요청당 상한까지입니다. N에 블록 가격을 곱한 값은 이보다 클 수 있습니다. 단위별로 청구되는 모든 실행은 같은 형태의 id로 가격을 확인합니다. <row>:<N>u는 그 행의 N단위 정확한 가격입니다. 예: apply-edl:4u, trim-video:5u, ltx-2.3-pro-retake:per-second:2.5u, elevenlabs-dubbing:3u. 보이스 체인저 Pro 변환 전체는 voice-changer-pro:<slot>,<slot>,…이며, @nodaro/shared의 voiceChangerProQuoteCreditId(slots)로 만듭니다. 단위별로 가격이 매겨지는 실행의 정확한 가격을 참고하세요.

credits.transactions(options?)

내 크레딧 거래 내역 한 페이지를 최신순으로 반환합니다(GET /v1/credits/transactions). Cloud 에디션 전용이며, 셀프 호스팅 설치는 404로 응답합니다.

transactions(options?: { limit?: number; cursor?: string }): Promise<CreditTransactionsPage>

속성

타입

페이지는 { data: CreditTransaction[], nextCursor }입니다. 더 읽을 행이 없으면 nextCursor는 null입니다.

필드형식설명
idstring거래 ID입니다.
created_atstringISO 8601 날짜입니다.
credits_chargednumber | null정산된 뒤 실행에 든 비용입니다. 홀드보다 적을 수 있고, 홀드가 환불되면 0이며, 홀드가 아직 열려 있는 동안에는 null입니다.
credits_reservednumber | null실행이 접수될 때 잡아 둔 홀드입니다. 바뀌지 않습니다.
credits_usednumber | null같은 홀드의 원래 이름으로, 기존 연동을 위해 유지됩니다. credits_charged를 쓰세요.
actionstring | null크레딧이 쓰인 모델 또는 작업입니다.
statusstring | null"reserved", "committed" 또는 "refunded"입니다.
metadataRecord<string, unknown>실행 자체의 청구 세부 정보입니다.
payer"user" | "workspace""workspace"는 내 잔액이 아니라 수업 또는 팀 예산에서 냈다는 뜻입니다.
workspaceIdstring | nullpayer가 "workspace"일 때 비용을 낸 워크스페이스입니다.

어떤 금액을 읽을지. 실행은 먼저 크레딧을 홀드한 뒤 정산됩니다. 홀드의 전부 또는 일부가 청구되고, 나머지는 잔액으로 돌아옵니다. 지출을 알려면 credits_charged를 더하세요. 크레딧을 참고하세요.

let cursor: string | undefined
let spent = 0
do {
  const page = await client.credits.transactions({ limit: 50, cursor })
  for (const t of page.data) spent += t.credits_charged ?? 0
  cursor = page.nextCursor ?? undefined
} while (cursor)
console.log(`${spent} credits charged`)

credits.claimWelcomeOffer(input?)

환영 혜택에 대한 사용자의 “예”를 한 번에 기록합니다(POST /v1/credits/welcome-offer/claim). 마케팅 이메일 수신 동의를 기록한 다음, 그 동의와 함께 가입 무료 지급을 요청합니다. 결정은 여전히 악용 검사가 내리므로 grant를 읽으세요. 지급이 이미 결정된 계정은 동의만 기록됩니다. Nodaro Cloud 전용이며, 셀프 호스팅 인스턴스는 404로 응답합니다.

claimWelcomeOffer(input?: WelcomeOfferClaimInput): Promise<WelcomeOfferClaimResult>

이 메서드에는 supabaseAuth()로 로그인한 브라우저 세션이 필요합니다. 동의는 사람의 선택이기 때문입니다. API 토큰이나 OAuth 앱 토큰은 403을 받습니다. 배포 환경에서 혜택이 꺼져 있는 동안에는 호출이 409 welcome_offer_disabled로 응답하므로, balance().welcomeOffer가 있을 때만 혜택을 보여 주세요.

WelcomeOfferClaimInput은 collectSignupKeys()가 반환한 SignupKeys에 sourceApp을 더한 것입니다. sourceApp은 소문자, 숫자, 대시로 된 최대 40자의 내 앱 슬러그입니다. 형식이 잘못된 슬러그는 거부되지 않고 없는 것으로 저장됩니다.

필드타입설명
consent"granted"이메일 수신 동의가 기록되었습니다.
grantFreeGrantState"granted": 지금 또는 이전에 지급되었습니다. "withheld": 악용 검사가 지급을 거부했습니다. "revoked": 이전에 지급이 회수되었습니다. "unclaimed": 아무것도 바뀌지 않았으므로 실패로 처리하고 사용자가 다시 시도하게 하세요.
creditsnumber지급 크레딧 수로, balance().welcomeOffer.credits와 같습니다. 지급은 구독 크레딧을 이 수까지 채웁니다. 그 위에 더해지지 않습니다.

WelcomeOfferState에는 필드가 세 개 있습니다. popupSeen(일회성 팝업이 표시됨), consentPending(계정에 크레딧이 있지만 아직 이메일 수신 동의가 남아 있음), credits(요청 시 지급되는 크레딧)입니다. 혜택에는 고정된 숫자 대신 credits 값을 보여 주세요. 이 값은 서버를 따릅니다.

credits.markWelcomeOfferSeen()

일회성 환영 팝업이 표시되었음을 기록하므로(POST /v1/credits/welcome-offer/seen), 모든 앱에서 welcomeOffer.popupSeen이 true가 됩니다. 다시 호출해도 아무것도 바뀌지 않습니다. 호출이 실패해도 팝업이 한 번 더 표시될 수 있을 뿐이므로 오류는 무시해도 됩니다. 규칙은 claimWelcomeOffer()와 같습니다.

markWelcomeOfferSeen(): Promise<{ ok: true }>
import { collectSignupKeys } from "@nodaro/sdk/signup-signals"

const { welcomeOffer } = await client.credits.balance()
if (welcomeOffer && !welcomeOffer.popupSeen) {
  showPopup({ credits: welcomeOffer.credits }) // the server's figure, never a constant
  void client.credits.markWelcomeOfferSeen().catch(() => {})
}

// On "Yes":
const keys = await collectSignupKeys()
const { grant, credits } = await client.credits.claimWelcomeOffer({ ...keys, sourceApp: "my-app" })
if (grant === "granted") showToast(`Your ${credits} free credits are ready`)

client.billing

client.billing은 판매 중인 요금제와 가격, 호출자의 구독, 배포 환경의 결제 방식을 읽습니다. 구매, 요금제 변경, 결제 설정은 Nodaro 앱에서 합니다. 그 경로는 API 토큰과 앱 토큰을 거부하므로 SDK에는 해당 메서드가 없습니다. 대신 사용자를 앱의 요금제 페이지로 안내하세요.

// A pricing screen: works signed out.
const { data: plans, topUps } = await client.billing.plans()

// Mark the plan the signed-in account is on.
const { effectiveTier } = await client.billing.subscription()
const current = plans.find((p) => p.id === effectiveTier) // undefined: pay-as-you-go, or a tier not on sale
메서드반환참고
plans()Promise<BillingPlansResult>GET /v1/billing/plans. 공개: 자격 증명이 필요 없으며, 모든 호출자에게 같은 응답을 줍니다. { data: BillingPlan[], topUps, topUpRange }를 반환합니다. Nodaro Cloud 전용이며, 셀프 호스팅 인스턴스는 NotFoundError를 발생시킵니다. 사용자에게 판매하지 않는 배포 환경은 ForbiddenError를 발생시킵니다. 잠시 가격을 읽을 수 없으면 상태 503의 NodaroError를 발생시킵니다.
subscription()Promise<BillingSubscriptionResult>GET /v1/billing/subscription. { data: BillingSubscription | null, effectiveTier }를 반환합니다. 계정이 구독한 적이 없으면 data는 null입니다. effectiveTier는 계정의 권한이 따르는 등급입니다. 보통 요금제 id이며, 구독 없이 크레딧을 구매했으면 "payg", 또는 "enterprise"처럼 판매하지 않는 등급입니다. 브라우저 세션, 워크플로 제한이 없는 개인 API 토큰, 또는 OAuth 앱 토큰이 필요합니다. Nodaro Cloud 전용입니다.
surface()Promise<BillingSurface>GET /v1/billing/surface. 공개이며, 모든 에디션에 있습니다. 배포 환경이 사용량을 측정하는지(측정하지 않으면 providerId가 "none"), 비용을 어떤 단위로 표시하는지(displayUnit) 알려 줍니다.
account()Promise<BillingAccountSummary | null>GET /v1/billing/account. 배포 환경의 결제 공급자가 보고하는 호출자의 plan, balance, dailyAllowance이며, 그 공급자의 unit으로 표시됩니다. 공급자가 응답하지 못하면 null이며, 이는 잔액 0이 아닙니다. 모든 에디션에 있습니다.

BillingPlan에는 다음 필드가 있습니다.

필드타입설명
idstring"free", "basic", "standard", "pro", "business" 중 하나입니다.
namestring표시 이름입니다.
prices{ monthly, yearly } | null무료 요금제는 null입니다. monthly는 { amount, currency, credits }입니다. yearly에는 연간 금액을 개월 수로 나눈 perMonth가 더해집니다. amount는 통화의 기본 단위이며(12는 12.00), currency는 "USD" 같은 ISO 4217 코드입니다. 지금 판매할 수 없는 가격은 null일 수 있으므로, 무료가 아니라 이용할 수 없음으로 표시하세요.
prices.*.credits{ amount, per } | null가격으로 지급되는 크레딧이며, per는 "month" 또는 "year"입니다. 연간 가격도 월간 가격처럼 요금제의 크레딧을 매달 지급합니다.
signupCreditsnumber | null무료 요금제에서 가입할 때 한 번 지급되는 크레딧입니다. 유료 요금제에서는 null입니다.
parallelismnumber워크플로 하나에서 동시에 실행되는 노드 수입니다.
storageBytesnumber내 미디어의 저장 공간으로, 바이트 단위입니다.

topUps는 크레딧 팩으로, { id, credits, price }이며 작은 것부터 나옵니다. 지금 가격을 알릴 수 없으면 price는 null입니다. topUpRange({ min, max, currency })는 앱에서 팩과 같은 비율로 크레딧으로 충전할 수 있는 정수 금액의 범위입니다. 요금제 없이 크레딧을 구매하는 방법은 구독 없는 API를 참고하세요.

모델과 가격 표시

모델마다 옆에 가격을 보여 주는, 노드 하나용 모델 선택기를 만드세요.

const { data: node } = await client.nodes.get("generate-video")
const { data: prices } = await client.credits.modelCosts(node.providers ?? [])

const options = (node.providers ?? []).map((id) => ({
  id,
  price: prices[id] ?? null, // null: no price on this instance
}))

노드의 기본 모델을 쓰려면 실행에서 provider를 생략하세요. 사용자가 모델을 고르면, 그 ID를 provider로 client.nodes.runAndWait()에 보내세요.

자주 묻는 질문

코드에서 Nodaro가 제공하는 모델을 나열하려면 어떻게 하나요?

client.models.list()를 호출하세요. 모든 이미지, 동영상, 오디오 모델을 종류와 제작사별로 묶어 반환하며, 모드, 화면 비율, 해상도, 길이와 함께 Nodaro Cloud에서는 크레딧 가격도 알려 줍니다.

실행하기 전에 모델 하나의 가격을 알아보려면 어떻게 하나요?

nano-banana-pro나 nano-banana-pro:4K 같은 모델의 가격 식별자를 넣어 client.credits.modelCosts를 호출하세요. data 필드가 각 식별자를 크레딧 가격에 대응시킵니다.

SDK로 내 크레딧 잔액을 확인하려면 어떻게 하나요?

client.credits.balance()를 호출하세요. total 필드는 사용할 수 있는 크레딧 수이며, 구독 크레딧과 충전 크레딧으로 나뉩니다.

SDK로 내 실행 비용을 합산하려면 어떻게 하나요?

각 페이지의 nextCursor로 client.credits.transactions()를 차례로 읽으며 credits_charged를 더하세요. 실행이 먼저 잡아 두는 credits_reserved는 실제로 낸 금액이 아닙니다.

내 앱에 Nodaro의 요금제와 가격을 보여 주려면 어떻게 하나요?

client.billing.plans()를 호출하세요. 로그인이 필요 없으며, 모든 요금제를 월간 및 연간 가격, 크레딧과 함께 반환하고 크레딧 팩도 반환합니다. 요금제 구매는 Nodaro 앱에서 합니다.

셀프 호스팅 설치에도 크레딧 가격이 있나요?

아니요. 셀프 호스팅한 Community Edition과 Business 에디션 설치에는 크레딧 시스템이 없으므로, 응답에 모델 가격과 크레딧 비용이 포함되지 않습니다.

최종 업데이트

목차