Create & Deploy an App Site
End-to-end guide: create an app, configure its privacy policy, subscribe, and deploy a live site.
This workflow takes you from zero to a live privacy policy page using the OrbitKit API.
Prerequisites: An OrbitKit account with an API key. See the Authentication guide if you haven’t set this up yet.
Steps
-
Create the app
curl -X POST https://api.orbitkit.io/api/apps \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{"appName": "My Weather App"}'var request = URLRequest(url: URL(string: "https://api.orbitkit.io/api/apps")!) request.httpMethod = "POST" request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization") request.setValue("application/json", forHTTPHeaderField: "Content-Type") request.httpBody = try JSONEncoder().encode(["appName": "My Weather App"]) let (data, _) = try await URLSession.shared.data(for: request) let app = try JSONDecoder().decode(CreateAppResponse.self, from: data) let appId = app.appIdconst res = await fetch("https://api.orbitkit.io/api/apps", { method: "POST", headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json", }, body: JSON.stringify({ appName: "My Weather App" }), }); const { appId } = await res.json();Save the
appIdfrom the response. -
Upload an icon (optional)
curl -X POST https://api.orbitkit.io/api/apps/$APP_ID/site/icon \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: image/png" \ --data-binary @icon.pnglet iconData = try Data(contentsOf: URL(fileURLWithPath: "icon.png")) 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 = iconData let (data, _) = try await URLSession.shared.data(for: request)const iconData = await fs.promises.readFile("icon.png"); const res = await fetch( `https://api.orbitkit.io/api/apps/${appId}/site/icon`, { method: "POST", headers: { Authorization: `Bearer ${token}`, "Content-Type": "image/png", }, body: iconData, } ); -
Configure the privacy policy
curl -X PUT https://api.orbitkit.io/api/apps/$APP_ID/policy \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{ "data": { "app-info": { "app_name": "My Weather App", "developer_name": "Weather Co", "email": "privacy@weather.co" }, "data-collection": { "collects_data": "yes", "data_types": ["location"], "purposes": ["app-functionality"] } } }'let policy: [String: Any] = [ "data": [ "app-info": [ "app_name": "My Weather App", "developer_name": "Weather Co", "email": "privacy@weather.co" ], "data-collection": [ "collects_data": "yes", "data_types": ["location"], "purposes": ["app-functionality"] ] ] ] var request = URLRequest(url: URL(string: "https://api.orbitkit.io/api/apps/\(appId)/policy")!) request.httpMethod = "PUT" request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization") request.setValue("application/json", forHTTPHeaderField: "Content-Type") request.httpBody = try JSONSerialization.data(withJSONObject: policy) let (data, _) = try await URLSession.shared.data(for: request)const res = await fetch( `https://api.orbitkit.io/api/apps/${appId}/policy`, { method: "PUT", headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json", }, body: JSON.stringify({ data: { "app-info": { app_name: "My Weather App", developer_name: "Weather Co", email: "privacy@weather.co", }, "data-collection": { collects_data: "yes", data_types: ["location"], purposes: ["app-functionality"], }, }, }), } ); -
Preview before deploying (optional)
curl -X POST https://api.orbitkit.io/api/apps/$APP_ID/preview \ -H "Authorization: Bearer $TOKEN"var request = URLRequest(url: URL(string: "https://api.orbitkit.io/api/apps/\(appId)/preview")!) request.httpMethod = "POST" request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization") let (data, _) = try await URLSession.shared.data(for: request)const res = await fetch( `https://api.orbitkit.io/api/apps/${appId}/preview`, { method: "POST", headers: { Authorization: `Bearer ${token}` }, } ); const preview = await res.json(); -
Subscribe the app
curl -X POST https://api.orbitkit.io/api/apps/$APP_ID/subscribe \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{"plan": "monthly"}'var request = URLRequest(url: URL(string: "https://api.orbitkit.io/api/apps/\(appId)/subscribe")!) request.httpMethod = "POST" request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization") request.setValue("application/json", forHTTPHeaderField: "Content-Type") request.httpBody = try JSONEncoder().encode(["plan": "monthly"]) let (data, _) = try await URLSession.shared.data(for: request) let result = try JSONDecoder().decode(SubscribeResponse.self, from: data)const res = await fetch( `https://api.orbitkit.io/api/apps/${appId}/subscribe`, { method: "POST", headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json", }, body: JSON.stringify({ plan: "monthly" }), } ); const { status } = await res.json();Handle the response based on
status(active,requires_payment_method, orrequires_action). -
Deploy
curl -X POST https://api.orbitkit.io/api/apps/$APP_ID/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 deploy = try JSONDecoder().decode(DeployResponse.self, from: data) print(deploy.url) // Live URLconst res = await fetch( `https://api.orbitkit.io/api/apps/${appId}/deploy`, { method: "POST", headers: { Authorization: `Bearer ${token}` }, } ); const { url } = await res.json();The response includes the live URL for your privacy policy.
What’s next
- Set up a custom domain for your app site
- Configure Universal Links for deep linking
- See the App Sites, Policy, and Sites & Deploy endpoint references for full details