Documentation

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