Images & Files
Upload app icons and Apple verification files via the OrbitKit API.
These endpoints handle binary file uploads for app icons and Apple verification files (.well-known).
Endpoints
| Method | Path | Description |
|---|---|---|
| POST | /api/apps/:appId/site/icon |
Upload app icon |
| POST | /api/apps/:appId/well-known/:fileName |
Upload a well-known file |
Upload app icon
POST /api/apps/:appId/site/icon
Upload an app icon image. Supported formats: PNG, JPEG, WebP (max 2 MB). The image is re-encoded server-side to a 512x512 PNG, stripping all metadata for security. The dominant color is automatically extracted and used for color-matched site backgrounds.
Rate limit: 10/hour per user
Request
Send the raw image bytes with the appropriate Content-Type header. Do not use application/json or multipart/form-data.
Full example
curl -X POST https://api.orbitkit.io/api/apps/-NtestApp123/site/icon \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: image/png" \
--data-binary @icon.png
let imageData = UIImage(named: "AppIcon")!.pngData()!
var request = URLRequest(url: URL(string: "https://api.orbitkit.io/api/apps/\(appId)/site/icon")!)
request.httpMethod = "POST"
request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization")
request.setValue("image/png", forHTTPHeaderField: "Content-Type")
request.httpBody = imageData
let (data, _) = try await URLSession.shared.data(for: request)
let result = try JSONDecoder().decode(IconResponse.self, from: data)
print(result.iconUrl) // GCS URL
const file = document.querySelector("input[type=file]").files[0];
const res = await fetch(`https://api.orbitkit.io/api/apps/${appId}/site/icon`, {
method: "POST",
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": file.type, // image/png, image/jpeg, or image/webp
},
body: file,
});
const { iconUrl, iconColor } = await res.json();
Response
{
"iconUrl": "https://storage.googleapis.com/orbitkit-sites/uid/appId/icon-1741621234567.png",
"iconColor": "#e8632b"
}
Errors
| Code | Status | When |
|---|---|---|
VALIDATION_FAILED |
400 | No image data, unsupported format, or file too large |
Upload a well-known file
POST /api/apps/:appId/well-known/:fileName
Uploads an Apple verification file to the .well-known directory. These files are served at https://your-site/.well-known/<fileName> after deploy.
Rate limit: 5/hour per user
Allowed files
| File name | Purpose |
|---|---|
apple-developer-domain-association.txt |
Sign in with Apple domain verification |
apple-developer-merchantid-domain-association |
Apple Pay domain verification |
apple-wallet-order-type-association |
Apple Wallet Order Type ID verification |
Request
Send the raw file bytes with Content-Type: application/octet-stream (max 100 KB).
Full example
curl -X POST https://api.orbitkit.io/api/apps/-NtestApp123/well-known/apple-developer-domain-association.txt \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/octet-stream" \
--data-binary @apple-developer-domain-association.txt
let fileURL = Bundle.main.url(forResource: "apple-developer-domain-association", withExtension: "txt")!
let fileData = try Data(contentsOf: fileURL)
var request = URLRequest(url: URL(string: "https://api.orbitkit.io/api/apps/\(appId)/well-known/apple-developer-domain-association.txt")!)
request.httpMethod = "POST"
request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization")
request.setValue("application/octet-stream", forHTTPHeaderField: "Content-Type")
request.httpBody = fileData
let (data, _) = try await URLSession.shared.data(for: request)
let result = try JSONDecoder().decode(WellKnownResponse.self, from: data)
print(result.fileName) // "apple-developer-domain-association.txt"
const file = document.querySelector("input[type=file]").files[0];
const res = await fetch(
`https://api.orbitkit.io/api/apps/${appId}/well-known/apple-developer-domain-association.txt`,
{
method: "POST",
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "application/octet-stream",
},
body: file,
}
);
const { success, fileName } = await res.json();
Response
{
"success": true,
"fileName": "apple-developer-domain-association.txt"
}
Errors
| Code | Status | When |
|---|---|---|
VALIDATION_FAILED |
400 | Invalid file name or empty file |