Documentation

Sites & Deploy

Deploy, preview, and manage site pages via the OrbitKit API.

Sites represent the hosted web presence for each app. Deploy renders all configured pages (privacy policy, support page, data deletion page, privacy labels, TestFlight page, AASA file) and publishes them to production.

Endpoints

Method Path Description
POST /api/apps/:appId/deploy Deploy site to production
GET /api/apps/:appId/deploy-history List deploy history
GET /api/apps/:appId/site/smart-banner Get Smart App Banner config
PUT /api/apps/:appId/site/smart-banner Save Smart App Banner config

Deploy site

POST /api/apps/:appId/deploy

Generates all pages and deploys them to production. Requires an active subscription for this app.

Rate limit: 10/hour per user

Full example

curl -X POST https://api.orbitkit.io/api/apps/-NtestApp123/deploy \
  -H "Authorization: Bearer $TOKEN"
var request = URLRequest(url: URL(string: "https://api.orbitkit.io/api/apps/\(appId)/deploy")!)
request.httpMethod = "POST"
request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization")

let (data, _) = try await URLSession.shared.data(for: request)
let result = try JSONDecoder().decode(DeployResult.self, from: data)
print(result.url) // "https://sites.orbitkit.io/my-weather-app/"
const res = await fetch(`https://api.orbitkit.io/api/apps/${appId}/deploy`, {
  method: "POST",
  headers: { Authorization: `Bearer ${token}` },
});
const { url, pages, deployedAt } = await res.json();

Response

{
  "url": "https://sites.orbitkit.io/my-weather-app/",
  "customDomainUrl": "https://privacy.myapp.com/",
  "deployedAt": 1712345678000,
  "pages": {
    "privacyPolicy": "https://sites.orbitkit.io/my-weather-app/privacy",
    "supportPage": "https://sites.orbitkit.io/my-weather-app/support",
    "dataDeletion": "https://sites.orbitkit.io/my-weather-app/delete",
    "nutritionLabels": "https://sites.orbitkit.io/my-weather-app/privacy-labels",
    "aasa": "https://sites.orbitkit.io/my-weather-app/.well-known/apple-app-site-association",
    "testflight": "https://sites.orbitkit.io/my-weather-app/testflight"
  },
  "customDomainPages": {
    "privacyPolicy": "https://privacy.myapp.com/privacy"
  }
}

The pages object only includes pages that exist for this app. customDomainPages is omitted if no custom domain is configured.

Errors

Code Status When
SUBSCRIPTION_REQUIRED 403 No active subscription
NOT_FOUND 404 Site or policy not configured
DEPLOY_FAILED 500 Server error during deploy

List deploy history

GET /api/apps/:appId/deploy-history

Returns the deploy history for an app, newest first (max 50 entries).

Response

[
  {
    "id": "-NabcDeployKey",
    "deployedAt": 1712345678000,
    "pages": ["home", "privacy", "support"],
    "slug": "my-weather-app",
    "customDomain": "privacy.myapp.com",
    "url": "https://sites.orbitkit.io/my-weather-app/"
  }
]

Get Smart App Banner config

GET /api/apps/:appId/site/smart-banner

Returns the Smart App Banner configuration, or null if not set.

Response

{
  "appStoreId": "123456789",
  "affiliateData": "ct=website",
  "appArgument": "weather://home",
  "appClipBundleId": "com.example.app.Clip",
  "appClipDisplay": "banner"
}

Save Smart App Banner config

PUT /api/apps/:appId/site/smart-banner

Request body

Field Type Required Description
appStoreId string Yes Numeric App Store ID
affiliateData string No Affiliate/campaign tracking data (max 200)
appArgument string No Deep link argument (max 500)
appClipBundleId string No App Clip bundle ID (max 200)
appClipDisplay string No "banner" or "card"

Response

Returns the saved Smart App Banner object.