npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@3dcade/sdk

v1.0.0

Published

Official 3Dcade SDK & CLI — text-to-3D generation, embeddable viewers, scenes, and marketplace API for Node.js

Downloads

122

Readme

@3dcade/sdk

Create, animate, embed, buy and sell 3D assets — from your terminal or Node.js app.

Official JavaScript / TypeScript SDK and CLI for the 3Dcade API. Turn text prompts into web-ready .glb models in seconds, embed them anywhere, and tap into scenes, marketplace, and advanced Meshy generation.

npm version npm downloads License: MIT Node.js

Links: Website · Twitter / X · npm @3dcade


Features

  • Text-to-3D — generate .glb models from a prompt (realistic, lowpoly, toon)
  • CLI3dcade generate, download, embed, list, and more from any terminal
  • TypeScript-first — full types, ESM + CJS, Node.js 18+
  • Advanced Meshy API — text/image-to-3D, retexture, rig, animate
  • Scenes & marketplace — create scenes, browse gallery, list and purchase assets
  • Embeddable viewer — get iframe HTML and viewer URLs for any ready model

Table of Contents


Install

Global (for the CLI)

npm install -g @3dcade/sdk
# or
pnpm add -g @3dcade/sdk
# or
yarn global add @3dcade/sdk

Local (for the SDK in your project)

npm install @3dcade/sdk
# or
pnpm add @3dcade/sdk

Get an API Key

  1. Sign in at 3dcade.studio
  2. Open Developer → API Keys
  3. Click New key, copy it

Quick Start — CLI

Step 1. Create a .env file in any directory:

echo "THREEDCADE_API_KEY=3dc_live_YOUR_KEY_HERE" > .env

Step 2. Generate your first model:

# Generate and wait for it to finish
3dcade generate "a low poly dragon" --style lowpoly --wait

# Output:
# ✓ Job created! Model ID: abc123xyz
# ✓ Model is ready!
#   ID              abc123xyz
#   GLB URL         https://cdn.3dcade.studio/models/abc123xyz.glb
#   Viewer          https://3dcade.studio/viewer/abc123xyz

Step 3. Download the .glb file:

3dcade download abc123xyz --output dragon.glb
# ✓ Saved: /your/dir/dragon.glb

CLI Commands

| Command | Description | |---|---| | 3dcade generate "<prompt>" | Generate a 3D model from a text prompt | | 3dcade status <id> | Check the status of a model | | 3dcade list | List all your models | | 3dcade download <id> | Download a model's .glb file | | 3dcade embed <id> | Get the viewer URL + iframe HTML | | 3dcade me | Show your account info and usage limits | | 3dcade health | Check API connectivity | | 3dcade help | Show full help |

generate options

| Flag | Default | Description | |---|---|---| | --style | realistic | Art style: realistic, lowpoly, toon | | --wait | false | Block until the model is ready | | --output <file> | — | Also download .glb to this path when --wait is used |

list options

| Flag | Default | Description | |---|---|---| | --status | — | Filter: pending, ready, failed | | --limit | 20 | Number of results per page | | --page | 1 | Page number |

download options

| Flag | Default | Description | |---|---|---| | --output <file> | <id>.glb | Output file path |


Quick Start — SDK

import ThreeDcadeClient from "@3dcade/sdk";

const client = new ThreeDcadeClient(process.env.THREEDCADE_API_KEY!);

// One-shot: generate + wait for completion
const model = await client.generateAndWait("a futuristic spaceship", "realistic", {
  onProgress: (m) => console.log(`Status: ${m.status} — ID: ${m.id}`),
});

console.log(model.glb_url);    // https://... .glb file URL
console.log(model.viewer_url); // https://... embeddable viewer URL

With .env via dotenv

import "dotenv/config"; // loads .env automatically
import ThreeDcadeClient from "@3dcade/sdk";

const client = new ThreeDcadeClient(process.env.THREEDCADE_API_KEY!);

CommonJS

const { ThreeDcadeClient } = require("@3dcade/sdk");

const client = new ThreeDcadeClient(process.env.THREEDCADE_API_KEY);

SDK API Reference

Constructor

new ThreeDcadeClient(apiKey: string, options?: { baseUrl?: string })

| Param | Type | Required | Description | |---|---|---|---| | apiKey | string | ✅ | Your 3dc_live_... API key | | options.baseUrl | string | ❌ | Override base URL (default: https://3dcade.studio/api) |


Text-to-3D (Simple)

client.generate(prompt, style?)

Start a generation. Returns immediately with a task ID.

const result = await client.generate("a red sports car", "realistic");
// result.id       — use to poll
// result.poll_url — polling URL

| Param | Type | Default | Description | |---|---|---|---| | prompt | string | required | Text description (max 300 chars) | | style | GenerationStyle | "realistic" | "realistic" | "lowpoly" | "toon" |


client.waitForModel(id, options?)

Poll until the model is ready or failed.

const model = await client.waitForModel("abc123", {
  intervalMs: 3000,
  timeoutMs: 300_000,
  onProgress: (m) => console.log(m.status),
});

| Option | Default | Description | |---|---|---| | intervalMs | 3000 | Polling interval in milliseconds | | timeoutMs | 300000 | Maximum wait time in milliseconds | | onProgress | — | Called on every poll with the current Model |


client.generateAndWait(prompt, style?, options?)

Shorthand: generate + wait. Returns the finished Model.

const model = await client.generateAndWait("a castle on a hill", "realistic");

client.getModel(id)

Fetch a model by ID.

const model = await client.getModel("abc123");
console.log(model.status); // "pending" | "ready" | "failed"

client.listModels(options?)

List models for this API key.

const { data, pagination } = await client.listModels({
  page: 1,
  limit: 20,
  status: "ready",
});

client.getEmbed(id)

Get embed data for a ready model.

const embed = await client.getEmbed("abc123");
console.log(embed.iframe_html);  // ready-to-paste <iframe>
console.log(embed.viewer_url);   // URL to the 3D viewer
console.log(embed.glb_url);      // direct .glb download link

client.deleteModel(id)

Delete a model.

await client.deleteModel("abc123");

Advanced Generation (Meshy)

These use your advanced daily quota and return a MeshyTask.

client.textTo3d(input)

const task = await client.textTo3d({
  prompt: "a medieval knight",
  art_style: "realistic",
  enable_pbr: true,
});
const finished = await client.waitForMeshyTask(task.task_id, {
  onProgress: (t) => console.log(`${t.status} — ${t.progress}%`),
});
console.log(finished.model_urls?.glb);

client.imageTo3d(input)

const task = await client.imageTo3d({
  image_url: "https://example.com/my-image.png",
  enable_pbr: true,
});

client.retexture(input)

Retexture an existing model with a new style prompt.

const task = await client.retexture({
  model_url: "https://cdn.../model.glb",
  prompt: "rusty iron armor",
});

client.rig(input) & client.animate(input)

const rigTask = await client.rig({ model_url: "https://cdn.../model.glb" });
const animTask = await client.animate({
  model_url: "https://cdn.../model.glb",
  prompt: "walking cycle",
});

client.waitForMeshyTask(taskId, options?)

Poll a Meshy task until SUCCEEDED or FAILED.

const result = await client.waitForMeshyTask(task.task_id, {
  intervalMs: 5000,
  timeoutMs: 600_000,
  onProgress: (t) => console.log(`${t.status} ${t.progress ?? 0}%`),
});

Scenes

// List scenes
const scenes = await client.listScenes({ page: 1, limit: 20 });

// Create
const scene = await client.createScene({ name: "My Scene", config: { ... } });

// Get / Update / Delete
await client.getScene(scene.id);
await client.updateScene(scene.id, { name: "Updated" });
await client.deleteScene(scene.id);

// Public embed (no auth needed)
const pub = await client.getPublicScene(scene.id);

// Snapshots
const snaps = await client.getSceneSnapshots(scene.id);

// Like
await client.toggleSceneLike(scene.id);

Community & Gallery

// Public gallery
const gallery = await client.getGallery({ sort: "trending", limit: 24 });

// Creator profile
const profile = await client.getCreatorProfile("wallet_address_here");

Marketplace

// Browse listings
const listings = await client.getMarketplace({ sort: "newest", limit: 12 });

// Detail + reviews
const detail = await client.getListingDetail("listing_id");

// Create a listing
const listing = await client.createListing({
  title: "Sci-Fi Ship Pack",
  price_sol: 0.1,
  scene_id: "scene_id",
});

// Purchase
await client.purchaseListing(listing.id, { transaction_signature: "sig..." });

// Review
await client.createReview(listing.id, { rating: 5, comment: "Amazing!" });

Account & Payments

// Your profile + usage limits
const me = await client.getMe();
console.log(me.tier);
console.log(me.limits.advanced_used, "/", me.limits.advanced_daily);

// SOL prices
const prices = await client.getPrices();

// Verify payment / upgrade tier
const updated = await client.verifyPayment({
  transaction_signature: "...",
  tier: "pro",
});

// Purchases & earnings
const library   = await client.getPurchases();
const earnings  = await client.getEarnings();

Error Handling

All API errors throw ThreeDcadeError:

import ThreeDcadeClient, { ThreeDcadeError } from "@3dcade/sdk";

const client = new ThreeDcadeClient(process.env.THREEDCADE_API_KEY!);

try {
  const model = await client.getModel("invalid-id");
} catch (err) {
  if (err instanceof ThreeDcadeError) {
    console.log(err.name);    // "ThreeDcadeError"
    console.log(err.code);    // "NOT_FOUND" | "MISSING_KEY" | "TIMEOUT" | ...
    console.log(err.message); // Human-readable description
    console.log(err.status);  // HTTP status code (e.g. 404)
  }
}

Common Error Codes

| Code | Status | Meaning | |---|---|---| | MISSING_KEY | — | apiKey was empty or not provided | | INVALID_PROMPT | — | Prompt is empty or over 300 chars | | NOT_FOUND | 404 | Model/scene/listing does not exist | | UNAUTHORIZED | 401 | Invalid or expired API key | | LIMIT_REACHED | 429 | Daily generation quota exhausted | | GENERATION_FAILED | — | Model failed during generation | | MESHY_TASK_FAILED | — | Advanced Meshy task failed or expired | | TIMEOUT | — | Polling timed out | | REQUEST_FAILED | varies | Generic HTTP error |


Environment Variables

| Variable | Required | Description | |---|---|---| | THREEDCADE_API_KEY | ✅ | Your 3dc_live_... API key | | THREEDCADE_BASE_URL | ❌ | Override the API base URL | | NO_COLOR | ❌ | Disable CLI color output | | DEBUG | ❌ | Print full error stack traces in CLI |

The CLI automatically reads .env from the current working directory — no extra setup needed.


Troubleshooting

command not found: 3dcade

You installed locally, not globally. Either:

npm install -g @3dcade/sdk        # install globally
# OR use npx:
npx @3dcade/sdk generate "prompt"

THREEDCADE_API_KEY is not set

Create a .env file in the directory where you run the command:

echo "THREEDCADE_API_KEY=3dc_live_YOUR_KEY" > .env

Or export it in your shell:

export THREEDCADE_API_KEY=3dc_live_YOUR_KEY

Model stuck on pending

Generation can take 1–3 minutes. Use --wait to block, or poll:

3dcade status <id>

LIMIT_REACHED error

You've used your daily generation quota. Upgrade your tier at 3dcade.studio → Pricing.

TypeScript: fetch is not defined

Requires Node.js ≥ 18 (which has fetch built-in). Check your version:

node --version  # should be v18.0.0 or higher

REST API (curl reference)

# Health check
curl https://3dcade.studio/api/v1/health

# Generate
curl -X POST https://3dcade.studio/api/v1/generate \
  -H "Authorization: Bearer 3dc_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"prompt": "a futuristic spaceship", "style": "realistic"}'

# Poll status
curl https://3dcade.studio/api/v1/model/TASK_ID \
  -H "Authorization: Bearer 3dc_live_YOUR_KEY"

# List models
curl "https://3dcade.studio/api/v1/models?page=1&limit=10" \
  -H "Authorization: Bearer 3dc_live_YOUR_KEY"

License

MIT — see LICENSE