This guide follows the domestic reconstruction task flow and adapts it to the overseas gateway. The public product name is Argus; endpoint paths still use vggt.
Create or select a Developer app
Open Apps and select the owning Team. Use an existing app, or have a Team owner choose Create trial app when there is capacity. Each Team may have up to three Developer apps; expired or disabled apps still count.
Creation saves an App request and completes it as soon as the app and AK binding are confirmed. The app uses the shared /open scope; there is no separate Argus capability application. Keep the SK and tokens on your backend. App availability, required inputs, resource access, and limits still apply.
The default 14-day trial is configured by the existing business process. Discuss production workflows or expected image volume in the Realsee Discord community, independently of request completion. Trial extensions require confirmation from the team.
Install the uploader
npm install @realsee/universal-uploader@0.1.1 cos-js-sdk-v5@1.8.3Argus uses the uploader to send the panorama to the temporary storage location returned by the gateway.
Get an Argus gateway token
Exchange your Developer app credentials through the same overseas gateway token endpoint used by OpenAPI. Send its raw token value in the Authorization header for Argus requests; no separate product credential application is required.
export async function getArgusAccessToken() {
const body = new URLSearchParams({
app_key: process.env.REALSEE_APP_KEY!,
app_secret: process.env.REALSEE_APP_SECRET!,
})
const response = await fetch('https://app-gateway.realsee.ai/auth/access_token', {
method: 'POST',
headers: { 'content-type': 'application/x-www-form-urlencoded' },
body,
})
if (!response.ok) throw new Error(`Argus auth failed: ${response.status}`)
const payload = await response.json() as {
code: number
status: string
data: { access_token: string }
}
if (payload.code !== 0) throw new Error(`Argus auth failed: ${payload.status}`)
return payload.data.access_token
}Create an upload token
Send an empty input_image_id to start a new upload session. The gateway returns the stable identifier that must be reused for upload, trigger, and poll requests.
import type { UploadToken } from '@realsee/universal-uploader'
export async function createArgusUpload(accessToken: string) {
const response = await fetch('https://app-gateway.realsee.ai/open/saas/v1/vggt/upload/token', {
method: 'POST',
headers: {
authorization: `${accessToken}`,
'content-type': 'application/json',
},
body: JSON.stringify({ input_image_id: '' }),
})
if (!response.ok) throw new Error(`Upload token failed: ${response.status}`)
const payload = await response.json() as {
code: number
status: string
data: {
input_image_id: string
upload_token: UploadToken
}
}
if (payload.code !== 0) throw new Error(`Upload token failed: ${payload.status}`)
return {
inputImageId: payload.data.input_image_id,
uploadToken: payload.data.upload_token,
}
}The response follows the gateway envelope used by other internal service calls: { code, status, data } with success code 0. Pass data.upload_token to the uploader, and retain data.input_image_id for the remaining requests.
Upload panoImage.jpg
The domestic walkthrough fixes the object key to panoImage.jpg. Keep that name unless your Realsee contact gives you a different contract.
Use Uploader.defaultUploadHandler for stable defaults, then override only when your file size requires different multipart settings.
import {
Uploader,
type ProviderAdaptor,
type UploadToken,
} from '@realsee/universal-uploader'
const cosAdaptor: ProviderAdaptor = () => import('@realsee/universal-uploader/adaptors/cos')
export async function uploadArgusPanorama(file: File, uploadToken: UploadToken) {
const uploader = new Uploader(cosAdaptor, {
getToken: async () => uploadToken,
})
return uploader.upload('panoImage.jpg', file, {
parallel: Uploader.defaultUploadHandler.parallel,
partSize: Uploader.defaultUploadHandler.partSize,
retry: Uploader.defaultUploadHandler.retry,
})
}Trigger reconstruction
After upload succeeds, trigger the Argus/VGGT task with the same input_image_id.
export async function triggerArgusTask(accessToken: string, inputImageId: string) {
const response = await fetch('https://app-gateway.realsee.ai/open/saas/v1/vggt/trigger', {
method: 'POST',
headers: {
authorization: `${accessToken}`,
'content-type': 'application/json',
},
body: JSON.stringify({
input_image_id: inputImageId,
type: 'pano',
}),
})
if (!response.ok) throw new Error(`Argus trigger failed: ${response.status}`)
return response.json()
}Poll until complete
Poll GET /open/saas/v1/vggt/poll with both type and input_image_id.
export async function pollArgusTask(accessToken: string, inputImageId: string) {
const url = new URL('https://app-gateway.realsee.ai/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}` },
})
if (!response.ok) throw new Error(`Argus poll failed: ${response.status}`)
const payload = await response.json() as {
code: number
status: string
data: {
status: 'pending' | 'success' | 'failed'
alg_task_id?: string
result_url?: string
failed_reason?: string
}
}
if (payload.code !== 0) throw new Error(`Argus poll failed: ${payload.status}`)
const data = payload.data
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')
}Successful responses can include result_url. The public schema guarantees only that this value is a URI; the media type and direct Five SDK compatibility depend on the provisioned integration.
Stable route summary
Use these stable docs URLs while building:
