Documentation

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

  1. 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.appId
    
    const 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 appId from the response.

  2. 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.png
    
    let 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,
      }
    );
    
  3. 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"],
            },
          },
        }),
      }
    );
    
  4. 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();
    
  5. 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, or requires_action).

  6. 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 URL
    
    const 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