# Integration Guide Build 3D rendering into your product with the DX.GL pipeline. --- ## Why Integrate Your users need product videos, turntable animations, or multi-view training datasets — but building a GPU rendering pipeline is a multi-year engineering effort. DX.GL handles the hard parts: model processing, GPU scheduling, shadow accumulation, video encoding, and asset delivery. You focus on your product. What this means in practice: - **Ship in days, not months** — a working integration takes hours. Upload a GLB, get back an MP4. The pipeline handles everything from model validation to poster extraction to web-optimized encoding. - **No GPU infrastructure** — DX.GL runs the render farm. You don't manage NVIDIA drivers, ffmpeg builds, or encoding queues. Scale from 10 renders to 10,000 without provisioning anything. - **Predictable costs** — credit-based pricing with volume discounts. Quote any batch before committing. No surprise compute bills. - **Production-grade output** — 1080p/4K H.264, ProRes 4444 with alpha, multi-view datasets with depth maps and camera poses. Every render includes a web variant, thumbnail, and poster automatically. Whether you're building an e-commerce platform, a 3D marketplace, a research data pipeline, or a content management system — the same API powers all of these. --- ## Architecture Overview ### Authentication You use a single API key (`dxgl_sk_...`) created in the [Portal](https://dx.gl/portal) → API Keys. All renders, uploads, and downloads are billed to your account. You handle user mapping and billing on your side however you want. ### Two Integration Paths | Path | Best for | How it works | |---|---|---| | **REST API** | Production pipelines, backend services | Direct HTTP calls from your server. Deterministic, testable, fully scriptable. | | **MCP (Model Context Protocol)** | Prototyping, ad-hoc tasks, AI-powered workflows | AI agents call DX.GL tools via natural language. Great for internal tooling and rapid iteration. | Both paths use the same underlying API and the same credit system. Many integrators start with MCP for prototyping and add direct REST calls for production. ### Credit Accounting Credits are deducted per render based on quality tier: | Quality | Output | Credits | |---|---|---| | `standard` | 1080p H.264 MP4 | 1 | | `4k` | 4K H.264 MP4 | 4 | | `pro` | 4K ProRes 4444 with alpha | 16 | | `dataset` 100×800 | 100-view training ZIP | 1 | | `dataset` 196×1024 | 196-view training ZIP | 4 | | `dataset` 400×2048 | 400-view training ZIP | 16 | Use the `quote` endpoint to check costs before committing. Batch renders deduct atomically — if you don't have enough credits, nothing is charged. --- ## Quick Start: REST API Base URL: `https://api.dx.gl/v1` All requests require `Authorization: Bearer dxgl_sk_...` in the header. ### 1. Upload a model ```bash curl -X POST https://api.dx.gl/v1/models \ -H "Authorization: Bearer dxgl_sk_..." \ -F "[email protected]" \ -F 'renderSettings={"aspect":"16:9","bgColor":"#ffffff","length":6}' ``` Response: ```json { "data": { "modelId": "Ab3kF9x2qL1m", "renderId": "Xz7pQ4w8nR2k" } } ``` The upload triggers a free system preview render automatically. If you pass `renderSettings`, a paid render is also queued. ### 2. Ingest from URL (no file upload) ```bash curl -X POST https://api.dx.gl/v1/models/ingest \ -H "Authorization: Bearer dxgl_sk_..." \ -H "Content-Type: application/json" \ -d '{"url": "https://your-cdn.com/model.glb", "renderSettings": {"aspect":"16:9"}}' ``` Same response format. The server downloads the file directly (max 100 MB, 2-minute timeout). SHA-256 deduplication prevents re-uploading identical files. ### 3. Create additional renders ```bash curl -X POST https://api.dx.gl/v1/renders \ -H "Authorization: Bearer dxgl_sk_..." \ -H "Content-Type: application/json" \ -d '{ "modelId": "Ab3kF9x2qL1m", "renderSettings": { "quality": "standard", "aspect": "1:1", "bgColor": "#000000", "length": 9, "shadows": true, "easing": true } }' ``` ### 4. Batch render (multiple variants at once) ```bash curl -X POST https://api.dx.gl/v1/renders/batch \ -H "Authorization: Bearer dxgl_sk_..." \ -H "Content-Type: application/json" \ -d '{ "renders": [ { "modelId": "Ab3kF9x2qL1m", "renderSettings": { "aspect": "16:9", "bgColor": "#ffffff" } }, { "modelId": "Ab3kF9x2qL1m", "renderSettings": { "aspect": "1:1", "bgColor": "#000000" } }, { "modelId": "Ab3kF9x2qL1m", "renderSettings": { "aspect": "9:16", "bgColor": "#ffffff" } } ] }' ``` Maximum 100 renders per batch. Credits deducted atomically. Renders for the same model share GPU frames — encoding multiple variants from one render pass. ### 5. Poll for completion ```bash curl https://api.dx.gl/v1/renders/Xz7pQ4w8nR2k \ -H "Authorization: Bearer dxgl_sk_..." ``` Status progression: `pending` → `poster-processing` → `poster-done` → `video-processing` → `done` The poster is available at `poster-done` — you can show it to users immediately while the video finishes encoding. ### 6. Download assets ```bash # Full video curl -o video.mp4 https://api.dx.gl/v1/renders/Xz7pQ4w8nR2k/video \ -H "Authorization: Bearer dxgl_sk_..." # Web-optimized variant (lower bitrate, faster loading) curl -o web.mp4 "https://api.dx.gl/v1/renders/Xz7pQ4w8nR2k/video?quality=web" \ -H "Authorization: Bearer dxgl_sk_..." # Poster image (full resolution) curl -o poster.png "https://api.dx.gl/v1/renders/Xz7pQ4w8nR2k/poster?quality=full" \ -H "Authorization: Bearer dxgl_sk_..." # All assets as ZIP curl -o assets.zip https://api.dx.gl/v1/renders/Xz7pQ4w8nR2k/bundle \ -H "Authorization: Bearer dxgl_sk_..." ``` All asset endpoints return `Cache-Control: immutable` — renders never change after completion. Safe to cache aggressively. ### Python Example ```python import requests, time API = "https://api.dx.gl/v1" HEADERS = {"Authorization": "Bearer dxgl_sk_..."} def render_model(glb_path, settings): """Upload a model, render it, return the video URL.""" with open(glb_path, "rb") as f: r = requests.post(f"{API}/models", headers=HEADERS, files={"file": f}, data={"renderSettings": json.dumps(settings)}) data = r.json()["data"] render_id = data["renderId"] # Poll until done while True: r = requests.get(f"{API}/renders/{render_id}", headers=HEADERS) status = r.json()["data"]["status"] if status == "done": return f"{API}/renders/{render_id}/video" if status == "error": raise Exception(f"Render failed: {r.json()['data'].get('errorMessage')}") time.sleep(3) # Usage url = render_model("chair.glb", {"aspect": "16:9", "bgColor": "#ffffff", "length": 6}) ``` ### Node.js Example ```javascript const API = 'https://api.dx.gl/v1'; const headers = { 'Authorization': 'Bearer dxgl_sk_...' }; async function renderModel(filePath, settings) { const form = new FormData(); form.append('file', fs.createReadStream(filePath)); form.append('renderSettings', JSON.stringify(settings)); const upload = await fetch(`${API}/models`, { method: 'POST', headers, body: form }); const { renderId } = (await upload.json()).data; // Poll until done while (true) { await new Promise(r => setTimeout(r, 3000)); const res = await fetch(`${API}/renders/${renderId}`, { headers }); const { status, errorMessage } = (await res.json()).data; if (status === 'done') return `${API}/renders/${renderId}/video`; if (status === 'error') throw new Error(`Render failed: ${errorMessage}`); } } ``` --- ## Quick Start: MCP Path The MCP server lets AI agents interact with DX.GL through tool calls. Add this to your MCP client configuration (Windsurf, Claude Desktop, Cursor, or any compatible host): ```json { "mcpServers": { "dxgl": { "serverUrl": "https://mcp.dx.gl/", "headers": { "Authorization": "Bearer dxgl_sk_..." } } } } ``` ### Available Tools | Tool | Description | |---|---| | `ingest_model` | Import a 3D model from a URL | | `list_models` | List models with tag and pagination filters | | `get_model` | Get model details and all its renders | | `create_render` | Create a single render (video or dataset) | | `create_batch_renders` | Create multiple renders atomically (max 100) | | `get_render` | Check render status (poll until done) | | `download_render` | Get download URL for a completed render | | `get_account` | Check credit balance | | `quote` | Estimate credit cost before committing | ### Example Prompts **Catalog onboarding:** > Import all GLB files from these URLs, tag them "client-acme", then render each in 16:9 white and 1:1 black with shadows. Quote the total first. **Variant expansion:** > For all models tagged "client-acme", create 9:16 renders with the branded gradient background (overlay ID abc123DEF456). Skip any that already have a 9:16 render. **Dataset generation:** > Generate 196×1024 hemisphere datasets for all models tagged "training-batch-7". Quote first, then proceed. **Status check:** > How many credits do I have left? List all pending renders and their status. ### When to Use MCP vs REST | Use MCP when... | Use REST when... | |---|---| | Prototyping a new integration | Running in production | | Ad-hoc batch operations | Automated backend pipeline | | Internal tooling for ops | User-facing render triggers | | Exploring the API interactively | Deterministic, testable code | Many teams use both: MCP for operations and internal tooling, REST for the production path. --- ## Common Integration Patterns ### Catalog Sync Upload new SKUs nightly from your product database. Tag each upload with a client or campaign identifier for easy filtering. ```python for sku in new_skus: r = requests.post(f"{API}/models/ingest", headers=HEADERS, json={ "url": sku["glb_url"], "renderSettings": {"aspect": "16:9", "bgColor": "#ffffff", "length": 6} }) model_id = r.json()["data"]["modelId"] # Tag the model requests.patch(f"{API}/models/{model_id}", headers=HEADERS, json={ "title": sku["name"], "sku": sku["sku_code"], "tags": ["client-acme", "fall-2026"] }) ``` ### On-Demand Rendering User uploads a model through your UI → your backend forwards it to DX.GL → polls for completion → delivers the video. ``` User → Your Frontend → Your Backend → DX.GL API → Poll → Deliver video URL ``` The poster is available at `poster-done` status — show it immediately as a preview while the video finishes. ### Variant Matrix Generate every combination of aspect ratio, background, and quality for each model: ```python variants = [ {"aspect": "16:9", "bgColor": "#ffffff", "shadows": True}, {"aspect": "1:1", "bgColor": "#000000", "shadows": True}, {"aspect": "9:16", "bgColor": "#ffffff", "reflector": True}, ] renders = [] for model_id in model_ids: for v in variants: renders.append({"modelId": model_id, "renderSettings": v}) # Submit all at once (max 100 per batch) for batch in chunks(renders, 100): r = requests.post(f"{API}/renders/batch", headers=HEADERS, json={"renders": batch}) ``` ### Background Image Branding Upload your client's branded background once, then reference it across all renders: ```bash # Upload the background image curl -X POST https://api.dx.gl/v1/overlays \ -H "Authorization: Bearer dxgl_sk_..." \ -F "[email protected]" \ -F "layer=background" \ -F "name=Acme Brand Gradient" # Use it in renders curl -X POST https://api.dx.gl/v1/renders \ -H "Authorization: Bearer dxgl_sk_..." \ -H "Content-Type: application/json" \ -d '{"modelId": "...", "renderSettings": {"bgImageId": "overlay_id_here", "aspect": "16:9"}}' ``` The image is scaled to cover the output dimensions and cropped from the top-left anchor, keeping logos safe across all aspect ratios. --- ## Tags for Multi-Tenant Organization Tags are the key to organizing models across clients, projects, and campaigns. Every model can have up to 20 tags (lowercased, trimmed). ### Tagging Strategy ``` client-{name} → per-client isolation (client-acme, client-widgets-inc) campaign-{name} → per-campaign grouping (campaign-fall-2026) batch-{id} → per-import-batch tracking status-{state} → workflow state (status-pending-review, status-approved) ``` ### Filtering ```bash # List all models for a specific client curl "https://api.dx.gl/v1/models?tags=client-acme&limit=100" \ -H "Authorization: Bearer dxgl_sk_..." # List models matching any of multiple tags (OR filter) curl "https://api.dx.gl/v1/models?tags=client-acme,campaign-fall-2026" \ -H "Authorization: Bearer dxgl_sk_..." ``` ### Per-Client Billing Tag every model with the client name. To calculate spend per client, list their models, count their renders, multiply by credit cost per quality tier. The `quote` endpoint can help estimate future costs. --- ## Credit Management ### Check Balance ```bash curl https://api.dx.gl/v1/account \ -H "Authorization: Bearer dxgl_sk_..." # Response: { "data": { "credits": 847 } } ``` ### Quote Before Committing ```bash curl -X POST https://api.dx.gl/v1/quote \ -H "Authorization: Bearer dxgl_sk_..." \ -H "Content-Type: application/json" \ -d '{"renders": [{"quality": "standard"}, {"quality": "standard"}, {"quality": "4k"}]}' # Response: { "data": { "creditsRequired": 6, "creditsAvailable": 847, "sufficient": true } } ``` Always quote large batches before submitting. The quote is free and returns per-item breakdown, total cost, and whether you have enough credits. ### Monitoring Build a simple dashboard that checks `GET /v1/account` periodically and alerts when credits drop below a threshold. Contact us for volume pricing at scale. --- ## Asset Delivery ### Public Share URLs Every completed render has a public share page at `https://dx.gl/portal/v/{renderId}`. No authentication required for viewing. Useful for sharing with stakeholders or embedding in emails. ### Direct Download All asset endpoints support `Range` headers for streaming and return `Cache-Control: immutable`. Assets per render: | Endpoint | Format | Use case | |---|---|---| | `GET /v1/renders/:id/video` | MP4 or MOV (Pro) | Full-quality download | | `GET /v1/renders/:id/video?quality=web` | MP4 (lower bitrate) | Web embedding, streaming | | `GET /v1/renders/:id/poster?quality=full` | PNG | Product page hero, social sharing | | `GET /v1/renders/:id/poster` | PNG (thumbnail) | Grid previews, hover states | | `GET /v1/renders/:id/thumb` | MP4 (quarter res) | Hover video preview | | `GET /v1/renders/:id/bundle` | ZIP | Bulk download of all assets | ### Embedding The web video variant is optimized for `<video>` tags: ```html <video autoplay loop muted playsinline> <source src="https://api.dx.gl/v1/renders/{id}/video?quality=web" type="video/mp4"> </video> ``` --- ## Render Settings Reference | Field | Type | Default | Description | |---|---|---|---| | `quality` | string | `"standard"` | `"standard"` (1080p), `"4k"` (4K), `"pro"` (4K ProRes with alpha) | | `aspect` | string | `"16:9"` | `"16:9"`, `"1:1"`, `"9:16"` | | `bgColor` | string | `"#ffffff"` | Any 6-digit hex (ignored when `bgImageId` is set) | | `bgImageId` | string | — | Overlay asset ID for background image | | `length` | integer | `6` | Duration in seconds (3–30) | | `shadows` | boolean | `true` | Ground shadows | | `reflector` | boolean | `false` | Reflective ground plane | | `easing` | boolean | `true` | Smooth rotation start/stop | | `rotateY` | integer | `0` | Starting angle (−180° to 180°) | | `tiltX` | integer | `0` | Forward/back tilt (−90° to 90°) | | `effect` | string | `"turntable"` | Camera motion: `"turntable"`, `"hero-spin"`, `"showcase"`, `"zoom-orbit"`, `"reveal"` | | `output` | string | `"video"` | `"video"` or `"dataset"` | | `datasetQuality` | string | — | `"100x800"`, `"196x1024"`, `"400x2048"` (when output is dataset) | | `coverage` | string | `"hemisphere"` | `"hemisphere"` or `"sphere"` (dataset only) | --- ## Error Handling All errors return a consistent format: ```json { "error": { "code": "no_credits", "message": "No render credits remaining", "status": 402 } } ``` Key error codes for integrators: | Code | Status | Action | |---|---|---| | `unauthorized` | 401 | Check API key | | `no_credits` | 402 | Purchase more credits or contact for volume pricing | | `file_too_large` | 400 | File exceeds 100 MB — reduce before upload | | `invalid_format` | 400 | Only GLB, glTF, and ZIP (OBJ+MTL) are supported | | `model_not_found` | 404 | Model was deleted or ID is wrong | | `too_many` | 400 | Batch exceeds 100 renders — split into smaller batches | | `upload_limit` | 429 | Free upload limit reached — purchase credits to unlock | --- ## Further Reading - [API Documentation](https://dx.gl/portal/docs) — Full REST API reference with all endpoints - [API Documentation (Markdown)](https://dx.gl/portal/docs/markdown) — Raw markdown, paste into LLM context - [MCP for Video](https://dx.gl/docs/mcp-video) — Automate video production with AI agents - [MCP for Datasets](https://dx.gl/docs/mcp-datasets) — Automate dataset generation with AI agents - [Portal Guide](https://dx.gl/portal/docs/guide) — Manual portal usage - [Pricing](https://dx.gl/pricing) — Credit packs and volume pricing - [Contact](https://dx.gl/contact) — Enterprise and integration inquiries