This tutorial walks you through creating your first 3D reconstruction task, from uploading an image to obtaining the final 3D output. Keep gateway access tokens and task orchestration on your backend. Return temporary upload credentials only to the authenticated client that is performing the upload, and do not log them.
Step 1: Install dependencies
npm install @realsee/universal-uploader@0.1.1 cos-js-sdk-v5@1.8.3Step 2: Request upload credentials
Send an empty input_image_id to create an upload session and request temporary credentials from the overseas Argus gateway. This request must use POST /open/saas/v1/vggt/upload/token and the Argus access token returned by /auth/access_token. Reuse the returned input_image_id for every later step.
The gateway wraps successful data in { code, status, data }, so read upload_token and input_image_id from data.
import type { UploadToken } from '@realsee/universal-uploader'
const ARGUS_GATEWAY = 'https://app-gateway.realsee.ai'
type ArgusEnvelope<T> = {
code: number
status: string
data: T
}
async function readArgusData<T>(response: Response): Promise<T> {
if (!response.ok) throw new Error(`Argus request failed: ${response.status}`)
const payload = await response.json() as ArgusEnvelope<T>
if (payload.code !== 0) throw new Error(`Argus request failed: ${payload.status}`)
return payload.data
}
export async function createArgusUpload(accessToken: string) {
const response = await fetch(`${ARGUS_GATEWAY}/open/saas/v1/vggt/upload/token`, {
method: 'POST',
headers: {
authorization: accessToken,
'content-type': 'application/json',
},
body: JSON.stringify({ input_image_id: '' }),
})
const data = await readArgusData<{
upload_token: UploadToken
input_image_id: string
}>(response)
return {
inputImageId: data.input_image_id,
uploadToken: data.upload_token,
}
}Step 3: Initialize the upload tool
import {
Uploader,
type ProviderAdaptor,
type UploadToken,
} from '@realsee/universal-uploader'
const cosAdaptor: ProviderAdaptor = () => import('@realsee/universal-uploader/adaptors/cos')
export function createArgusUploader(uploadToken: UploadToken) {
return new Uploader(cosAdaptor, {
getToken: async () => uploadToken,
})
}Step 4: Upload the image
Configuration parameters
key: string— object name; use the required fixed namepanoImage.jpg.file— panorama content as aFileorBlob.
Add the image-upload method:
export async function uploadArgusPanorama(file: File, uploadToken: UploadToken) {
const uploader = createArgusUploader(uploadToken)
return uploader.upload('panoImage.jpg', file, {
parallel: Uploader.defaultUploadHandler.parallel,
partSize: Uploader.defaultUploadHandler.partSize,
retry: Uploader.defaultUploadHandler.retry,
})
}Step 5: Trigger the VGGT depth task
After the upload succeeds, trigger reconstruction with the same input_image_id.
- Endpoint: POST /open/saas/v1/vggt/trigger
- Example parameters:
{
"input_image_id": "2aa48574-86a7-41ae-9643-xxxx",
"type": "pano"
}Add the task-creation method:
export async function triggerArgusTask(accessToken: string, inputImageId: string) {
const response = await fetch(`${ARGUS_GATEWAY}/open/saas/v1/vggt/trigger`, {
method: 'POST',
headers: {
authorization: accessToken,
'content-type': 'application/json',
},
body: JSON.stringify({
input_image_id: inputImageId,
type: 'pano',
}),
})
return readArgusData<Record<string, unknown>>(response)
}Step 6: Poll until the task completes
Poll the overseas gateway with both type=pano and the same input_image_id.
- Endpoint:
GET /open/saas/v1/vggt/poll?type=pano&input_image_id=id - Logic:
- Periodically query the task status (
pending→successorfailed) - On success, return the output metadata documented by the provisioned integration
- Periodically query the task status (
Add the task-status polling method:
type ArgusTaskStatus = {
status: 'pending' | 'success' | 'failed'
alg_task_id?: string
result_url?: string
failed_reason?: string
}
export async function pollArgusTask(accessToken: string, inputImageId: string) {
const url = new URL(`${ARGUS_GATEWAY}/open/saas/v1/vggt/poll`)
url.searchParams.set('type', 'pano')
url.searchParams.set('input_image_id', inputImageId)
for (let attempt = 0; attempt < 90; attempt += 1) {
const response = await fetch(url, {
headers: { authorization: accessToken },
})
const data = await readArgusData<ArgusTaskStatus>(response)
if (data.status === 'success') return data
if (data.status === 'failed') throw new Error('Argus task failed')
await new Promise((resolve) => setTimeout(resolve, 2000))
}
throw new Error('Argus task timed out')
}See the Argus API Reference for the complete request and response contract.
