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
- User generates an API key on Arrival Space
- Third Party uses the key to upload files on behalf of that user
- After uploading to S3, confirm the upload to receive the final URL
- 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}.
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
- Log in to Arrival Space
- Navigate to your account settings
- 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 Code | Description |
|---|---|
400 | Bad Request — Invalid parameters |
401 | Unauthorized — Invalid or expired API key |
403 | Forbidden — Insufficient permissions |
413 | Payload Too Large — File exceeds size limit |
507 | Insufficient Storage — User storage quota exceeded |
500 | Internal 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