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.
Submit App request
Argus is reviewed before production use. Submit an App request from /dashboard/apps/apply and include:
- App name - the product or integration that will use Argus.
- Production use case - the workflow, why AI reconstruction is needed, and the approximate monthly panorama volume.
- Contact name - the person Realsee can contact during review.
- Contact email - the address the Realsee developer team can use during review.
The request is automatically scoped to the active Team from your signed-in session; Team ownership is not editable in the form. After approval, the provisioned Developer app appears in the Team dashboard. Use its app key and app secret only on your backend.
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 reviewed Developer app credentials for an Argus gateway access token. This is separate from the regular OpenAPI auth docs because Argus has its own reviewed gateway surface.
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:
