# Map Upload

The VPS mapping APIs work together in a two-step process to upload large map files efficiently using S3 multipart upload. Here's how to use them:

\
**Step 1**: Create Map - Call **POST /v2/vps/map** with your map metadata (name, coordinates, file size, etc.). This API validates your account limits, creates a map entry in the database, and returns multiple presigned S3 URLs for uploading file chunks. You'll receive a mapId, uploadId, and an array of signedUrls for parallel uploads.

Choose source object based on scan type

```
  "source": {
    "provider": "unity", // matterport // leica // navvis // xgrid // faro
    "fileType": "zip", // e57
    "coordinateSystem": "RHS" // LHS
  }
```

For example, the source object for Matterport e57 and Navvis will be

```
    "provider": "matterport"
    "fileType": "e57"
    "coordinateSystem": "RHS"
  }
```

```
    "provider": "navvis"
    "fileType": "e57"
    "coordinateSystem": "RHS"
  }
```

For example, the source object for Matterport e57 will be

\
**Step 2**: Upload File Parts - Split your map file into chunks and upload each chunk to the corresponding presigned URL using standard HTTP PUT requests. Each successful upload returns an ETag, which you must capture and store.

\
**Step 3**: Complete Upload - Call **POST /v2/vps/map/complete-upload/{mapId}** with the uploadId, S3 key, and an array of all the ETags and PartNumbers from step 2. This finalizes the S3 multipart upload, combines all chunks into a single file, and marks your map as ready for processing.

\
The entire process supports large files up to 25GB, provides progress tracking during uploads, allows for retry logic on failed parts, and includes comprehensive error handling for account limits,authentication, and upload failures. Once completed successfully, your map will enter the processing queue and be available for VPS queries within your application.

## Create a new VPS map

> Creates a new VPS map entry and initiates the S3 multipart upload process. This endpoint\
> validates the map data, checks account limits, and returns S3 upload URLs for file upload.<br>

```json
{"openapi":"3.0.0","info":{"title":"Create VPS Map API","version":"2.0.0"},"servers":[{"url":"https://api.multiset.ai/v2","description":"Production server"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"Standard Authorization header using the Bearer scheme. Example: \"Authorization: Bearer {token}\""}},"schemas":{"VPSMapCreationResponse":{"type":"object","properties":{"message":{"type":"string","description":"Success message"},"mapCode":{"type":"string","description":"Unique code for the created VPS map"},"mapId":{"type":"string","description":"Unique identifier for the created VPS map"},"uploadUrls":{"type":"object","description":"S3 multipart upload URLs and metadata","properties":{"uploadId":{"type":"string","description":"S3 multipart upload ID"},"signedUrls":{"type":"array","description":"Array of upload URLs for each part","items":{"type":"object","properties":{"partNumber":{"type":"integer","description":"Part number for multipart upload"},"signedUrl":{"type":"string","format":"uri","description":"Presigned URL for uploading this part"}}}}}},"key":{"type":"string","description":"S3 key path for the uploaded file"}},"required":["message","mapCode","mapId","uploadUrls","key"]},"Error":{"type":"object","properties":{"message":{"type":"string","description":"Error message detailing what went wrong"}},"required":["message"]}}},"paths":{"/vps/map":{"post":{"summary":"Create a new VPS map","description":"Creates a new VPS map entry and initiates the S3 multipart upload process. This endpoint\nvalidates the map data, checks account limits, and returns S3 upload URLs for file upload.\n","tags":["VPS"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"mapName":{"type":"string","description":"Human-readable name for the VPS map"},"fileSize":{"type":"number","description":"Size of the file to be uploaded in bytes","minimum":1},"coordinates":{"type":"object","description":"Geographic coordinates for the map","properties":{"latitude":{"type":"number","minimum":-90,"maximum":90,"description":"Latitude coordinate"},"longitude":{"type":"number","minimum":-180,"maximum":180,"description":"Longitude coordinate"},"altitude":{"type":"number","description":"Altitude in meters"}},"required":["latitude","longitude","altitude"]},"heading":{"type":"number","minimum":0,"maximum":360,"description":"Optional heading direction in degrees"},"source":{"type":"object","description":"Source information for the map data","properties":{"provider":{"type":"string","enum":["unity","matterport","leica","navvis"],"description":"Data provider platform"},"fileType":{"type":"string","enum":["zip","e57"],"description":"File format of the map data"},"coordinateSystem":{"type":"string","enum":["LHS","RHS"],"description":"Coordinate system (Left-Hand or Right-Hand)"}}}},"required":["mapName","fileSize","coordinates"]}}}},"responses":{"201":{"description":"VPS map created successfully with upload URLs","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VPSMapCreationResponse"}}}},"400":{"description":"Bad request - Invalid input data, plan limits exceeded, or plan expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized - Missing or invalid token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}
```

## Complete VPS map multipart upload

> Completes the S3 multipart upload process for a VPS map. This endpoint should be called\
> after all file parts have been uploaded to S3 using the provided upload URLs.<br>

```json
{"openapi":"3.0.0","info":{"title":"Complete VPS Map Upload API","version":"2.0.0"},"servers":[{"url":"https://api.multiset.ai/v2","description":"Production server"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"Standard Authorization header using the Bearer scheme. Example: \"Authorization: Bearer {token}\""}},"schemas":{"VPSMapCompletionResponse":{"type":"object","properties":{"message":{"type":"string","description":"Success message"}},"required":["message"]},"Error":{"type":"object","properties":{"message":{"type":"string","description":"Error message detailing what went wrong"}},"required":["message"]}}},"paths":{"/vps/map/complete-upload/{id}":{"post":{"summary":"Complete VPS map multipart upload","description":"Completes the S3 multipart upload process for a VPS map. This endpoint should be called\nafter all file parts have been uploaded to S3 using the provided upload URLs.\n","tags":["VPS"],"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string","pattern":"^[a-fA-F0-9]{24}$"},"description":"Unique identifier of the VPS map (MongoDB ObjectId)"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"uploadId":{"type":"string","description":"The upload ID returned from the map creation endpoint"},"key":{"type":"string","description":"The S3 key for the uploaded file"},"parts":{"type":"array","description":"Array of uploaded parts with their ETags","items":{"type":"object","properties":{"ETag":{"type":"string","description":"ETag returned by S3 for the uploaded part"},"PartNumber":{"type":"number","minimum":1,"description":"Part number (starting from 1)"}},"required":["ETag","PartNumber"]},"minItems":1}},"required":["uploadId","key","parts"]}}}},"responses":{"200":{"description":"VPS map multipart upload completed successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VPSMapCompletionResponse"}}}},"400":{"description":"Bad request - Invalid upload data or missing required fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized - Missing or invalid token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found - VPS map not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal server error during upload completion","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}
```
