Skip to main content

Arrival Space File Upload API

Version: 1.0
Last Updated: December 4, 2025

Overview

The integration allows third-party applications to upload assets directly to a user's Arrival Space. This is just the beginning — we will be adding more functionality to the API in future updates.

Flow Summary

  1. User generates an API key on Arrival Space
  2. Third Party uses the key to upload files on behalf of that user
  3. After uploading to S3, confirm the upload to receive the final URL
  4. Use the final URL to create a new space in Arrival Space

Configuration

const API_BASE_URL = "https://api-staging.arrival.space/api";
const VERSION = "v1";

All endpoints should be prefixed with ${API_BASE_URL}/${VERSION}.

note

The API endpoint may change in the future. If you experience any connection issues, please reach out to our support team.


Authentication

All API requests require a Bearer token in the Authorization header:

Authorization: Bearer <api_key>

Obtaining an API Key

  1. Log in to Arrival Space
  2. Navigate to your account settings
  3. Generate or Copy the previously generated API key

Endpoints

1. Request Upload URL

POST /files/upload

Generates a presigned S3 URL for file upload.

Request

Headers:

const headers = {
Authorization: `Bearer ${api_key}`,
"Content-Type": "application/json"
};

Body:

const body = {
file_name: "example.zip", // Name of the file
file_size: 1048576000, // File size in bytes
content_type: "application/zip" // MIME type
};

Response

{
"status": "ok",
"data": {
"upload_type": "presigned_url",
"params": {
"url": "https://s3.amazonaws.com/bucket/...?X-Amz-Signature=...",
"method": "PUT",
"headers": { "Content-Type": "application/zip" }
}
}
}

Upload to S3

Once you receive the presigned URL, use the returned params to upload the file directly to S3:

fetch(params.url, {
method: params.method,
headers: params.headers,
body: file,
});

2. Confirm Upload

POST /files/upload-complete

Call this after the file has been successfully uploaded to S3. Confirms the upload is complete and returns the resource key you can later use to create a space or other entities.

Request

Headers:

const headers = {
Authorization: `Bearer ${api_key}`,
"Content-Type": "application/json"
};

Body:

const body = {
status: "success",
extra_info: {
file_url: "https://s3.amazonaws.com/bucket/uploads/example.zip"
}
};

Response

{
"status": "confirmed",
"data": {
"resource_key": "api-uploads/...ply"
}
}

3. Create Space

POST /user/create-space

Creates a new space in Arrival Space with the key to the uploaded file. Call this after confirming the upload.

Request

Headers:

const headers = {
Authorization: `Bearer ${api_key}`,
"Content-Type": "application/json"
};

Body:

const body = {
space_data: {
title: "My New Space", // Title for the space (optional)
description: "Optional description", // Description (optional)
resource_key: "api-uploads/...ply", // resource_key from upload-complete (optional: if not provided an empty space is created)
}
};

Response

{
"status": "ok",
"message": "Space created successfully",
"data": {
"space_url": "https://arrival.space/12345678_9012",
"title": "My New Space"
}
}

Complete Integration Example

const API_BASE_URL = "https://api-staging.arrival.space/api";
const VERSION = "v1"

async function uploadFileToArrivalSpace(apiKey, file, spaceTitle, spaceDescription = "") {
// Step 1: Request presigned upload URL
const uploadRequest = await fetch(`${API_BASE_URL}/${VERSION}/files/upload`, {
method: "POST",
headers: {
Authorization: `Bearer ${apiKey}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
file_name: file.name,
file_size: file.size,
content_type: file.type
})
});

if (!uploadRequest.ok) {
throw new Error("Failed to get upload URL");
}

const { data } = await uploadRequest.json();
const { params } = data;

// Step 2: Upload file to S3
const s3Upload = await fetch(params.url, {
method: params.method,
body: file,
headers: params.headers
});

if (!s3Upload.ok) {
throw new Error("Failed to upload file to S3");
}

// Step 3: Confirm upload and get final URL
const fileUrl = params.url.split('?')[0]; // Remove query params
const confirmRequest = await fetch(`${API_BASE_URL}/${VERSION}/files/upload-complete`, {
method: "POST",
headers: {
Authorization: `Bearer ${apiKey}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
status: "success",
extra_info: {
file_url: fileUrl
}
})
});

if (!confirmRequest.ok) {
throw new Error("Failed to confirm upload");
}

const confirmData = await confirmRequest.json();
const resource_key = confirmData.data.resource_key;

// Step 4: Create space with uploaded file
const createSpaceRequest = await fetch(`${API_BASE_URL}/${VERSION}/user/create-space`, {
method: "POST",
headers: {
Authorization: `Bearer ${apiKey}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
space_data: {
title: spaceTitle,
description: spaceDescription,
resource_key: resource_key,
}
})
});

if (!createSpaceRequest.ok) {
throw new Error("Failed to create space");
}

return await createSpaceRequest.json();
}

// Usage
const apiKey = "your_api_key_here";
const file = document.getElementById("fileInput").files[0];

uploadFileToArrivalSpace(apiKey, file, "My New Space", "Optional description")
.then(result => console.log("Space created:", result.data))
.catch(error => console.error("Upload failed:", error));

Error Handling

Status CodeDescription
400Bad Request — Invalid parameters
401Unauthorized — Invalid or expired API key
403Forbidden — Insufficient permissions
413Payload Too Large — File exceeds size limit
507Insufficient Storage — User storage quota exceeded
500Internal Server Error

Notes

  • API keys are tied to individual user accounts
  • Uploaded files create spaces owned by the API key holder
  • Presigned URLs expire after a limited time — upload promptly
  • Keep your API key secure and never expose it in client-side code