v1STABLE

API Documentation

The SunTrace3D Partner API lets you generate HD 3D city models, calculate solar energy yield, and embed interactive 3D viewers on your website. All endpoints use JSON and standard HTTP methods.

View as Markdown (machine-readable)
1

Overview

The SunTrace3D API is a RESTful service for programmatic access to 3D city model generation and solar energy calculations. The API is designed for partners who want to integrate solar analysis into their own applications, websites, or workflows.

Base URL

https://suntrace3d.com/api/v1
REST API
JSON request/response
Bearer Auth
API key authentication
HD Quality
All API models are HD

Available Endpoints

POST/api/v1/modelsGenerate a new HD 3D model
GET/api/v1/models/:idCheck model generation status
POST/api/solar/calculateCalculate solar energy yield
GET/embedEmbeddable 3D viewer (iframe)
GET/api/healthHealth check (no auth required)
Partner portal showing API keys and usage statistics
The Partner Portal — manage API keys, view usage statistics, and get embed code
2

Authentication

All API requests require authentication via a Bearer token in the Authorization header. API keys are managed through the Partner Portal.

Getting an API key

  1. 1
    Create an account
    Sign up at /auth/signup if you haven't already.
  2. 2
    Upgrade to Pro
    A Pro subscription is required for API access. Upgrade from your account settings.
  3. 3
    Generate an API key
    Visit the Partner Portal and click "Create Key". Copy your key immediately — it won't be shown again.
  4. 4
    Use in requests
    Include the key in all API requests as a Bearer token.
Authentication Headerbash
curl -H "Authorization: Bearer st_live_abc123def456..." \
  https://suntrace3d.com/api/v1/models

Keep your API key secret

Never expose your API key in client-side JavaScript, public repositories, or front-end code. If your key is compromised, revoke it immediately from the Partner Portal and create a new one.

3

Generate a 3D Model

Request the generation of an HD 3D city model for a specific geographic location. The model is generated asynchronously — poll the status endpoint to check when it's ready.

POST/api/v1/models

Request Body

latitudenumberrequiredLatitude of the center point (-90 to 90)
longitudenumberrequiredLongitude of the center point (-180 to 180)
radiusKmnumberRadius of the area to model in km (default: 0.3)

Response

idstringrequiredUnique model identifier for status polling
statusstringrequired"pending" | "processing" | "ready" | "failed"
modelUrlstringURL to the GLB model file (when ready)
progressnumberGeneration progress 0-100 (when processing)
stepstringCurrent generation step description
Requestbash
curl -X POST https://suntrace3d.com/api/v1/models \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "latitude": 44.8699,
    "longitude": 13.8420,
    "radiusKm": 0.3
  }'
Response (pending)json
{
  "id": "hd_44.8699_13.8420_0.3",
  "status": "pending"
}
Response (ready)json
{
  "id": "hd_44.8699_13.8420_0.3",
  "status": "ready",
  "modelUrl": "https://s3.eu-central-1.amazonaws.com/suntrace-models/hd_44.8699_13.8420_0.3/scene.glb"
}

Model caching

If a model for the same location and radius has already been generated, the API returns the cached result immediately with status: "ready". Models are cached in S3 for 30 days. You are not charged for cached results.

API request generating a 3D model
The API generates HD 3D models asynchronously — poll the status endpoint until ready
4

Check Model Status

Poll this endpoint to check the status of a model generation request. The model goes through several stages: pendingprocessingready.

GET/api/v1/models/:id
Requestbash
curl https://suntrace3d.com/api/v1/models/hd_44.8699_13.8420_0.3 \
  -H "Authorization: Bearer YOUR_API_KEY"
Response (processing)json
{
  "id": "hd_44.8699_13.8420_0.3",
  "status": "processing",
  "progress": 65,
  "step": "Generating textures..."
}
Response (ready)json
{
  "id": "hd_44.8699_13.8420_0.3",
  "status": "ready",
  "modelUrl": "https://s3.eu-central-1.amazonaws.com/suntrace-models/hd_44.8699_13.8420_0.3/scene.glb",
  "progress": 100,
  "step": null
}

Status Values

pendingJob is queued and waiting to be picked up by a worker
processingModel is being generated. Check progress field for percentage.
readyModel is ready. The modelUrl field contains the download URL.
failedGeneration failed. You can retry by creating a new request.

Polling recommendation

We recommend polling every 5-10 seconds. Typical generation times are 30-120 seconds depending on the area size and server load. The progress field provides a percentage (0-100) to show a progress indicator in your UI.

5

Calculate Solar Energy

Calculate annual solar energy yield for a specific panel configuration and location. This endpoint uses PVGIS (Photovoltaic Geographical Information System) satellite data for accurate irradiance values.

POST/api/solar/calculate

Request Body

latitudenumberrequiredLocation latitude
longitudenumberrequiredLocation longitude
tiltDegnumberrequiredPanel tilt angle in degrees (0-90)
azimuthDegnumberrequiredPanel azimuth in degrees (0=North, 180=South)
panelAreaM2numberrequiredTotal panel area in square meters
panelEfficiencynumberrequiredPanel efficiency (0.0 - 1.0, typically 0.18-0.22)
shadingLossFractionnumberShading loss factor (0.0-1.0, default: 0)

Response

annualYieldKwhnumberrequiredEstimated annual energy yield in kWh
peakPowerKwnumberrequiredPeak power output in kW
specificYieldnumberrequiredSpecific yield in kWh/kWp
monthlyKwhnumber[]requiredArray of 12 monthly kWh values
sourcestringrequiredData source identifier ("pvgis")
Requestbash
curl -X POST https://suntrace3d.com/api/solar/calculate \
  -H "Content-Type: application/json" \
  -d '{
    "latitude": 44.8699,
    "longitude": 13.8420,
    "tiltDeg": 35,
    "azimuthDeg": 180,
    "panelAreaM2": 20,
    "panelEfficiency": 0.20,
    "shadingLossFraction": 0.05
  }'
Responsejson
{
  "annualYieldKwh": 4982,
  "peakPowerKw": 4.0,
  "specificYield": 1246,
  "monthlyKwh": [248, 305, 412, 465, 522, 548, 562, 530, 445, 368, 280, 232],
  "source": "pvgis"
}

No authentication required

The solar calculation endpoint is publicly available and does not require an API key. It uses the PVGIS public API maintained by the European Commission's Joint Research Centre.

Solar energy calculation API response
The solar calculation API returns annual yield, peak power, and monthly breakdown
6

Embed Viewer

Embed an interactive 3D solar viewer on your website using an iframe. The embed viewer includes time controls for shadow simulation and works on both desktop and mobile.

Embed URL Parameters

latnumberrequiredLatitude of the location to display
lngnumberrequiredLongitude of the location to display
keystringrequiredYour API key for authentication
Basic Embed Codehtml
<iframe
  src="https://suntrace3d.com/embed?lat=44.8699&lng=13.8420&key=YOUR_API_KEY"
  width="100%"
  height="500"
  frameborder="0"
  allow="fullscreen"
  style="border-radius: 12px; border: 1px solid #e5e7eb;">
</iframe>
Responsive Embed (recommended)html
<div style="position: relative; width: 100%; padding-bottom: 56.25%; overflow: hidden; border-radius: 12px;">
  <iframe
    src="https://suntrace3d.com/embed?lat=44.8699&lng=13.8420&key=YOUR_API_KEY"
    style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border: none;"
    allow="fullscreen">
  </iframe>
</div>

Embed features

Interactive 3D orbit, pan, and zoom
Time slider for shadow simulation
Responsive — works on mobile
Google 3D Tiles photorealistic models
No additional JavaScript required
Fullscreen support
Embedded 3D viewer in an iframe
The embeddable viewer includes time controls and works on both desktop and mobile
7

Rate Limits

The API enforces rate limits to ensure fair usage and system stability.

Model Generation
POST /api/v1/models
10 requests
per hour, per API key
Status Polling
GET /api/v1/models/:id
No limit
Poll as needed
Solar Calculation
POST /api/solar/calculate
No limit
Public endpoint
Embed Views
GET /embed
No limit
Unlimited views
Rate Limit Exceeded Response (429)json
{
  "error": "Rate limit exceeded. Maximum 10 generations per hour."
}
8

Error Handling

The API uses standard HTTP status codes. All error responses include a JSON body with anerror field describing the problem.

HTTP Status Codes

200Success — request completed successfully
400Bad Request — missing or invalid parameters
401Unauthorized — missing or invalid API key
404Not Found — model ID does not exist
429Too Many Requests — rate limit exceeded
503Service Unavailable — external service (PVGIS) is down
Error Response Examplejson
{
  "error": "latitude and longitude are required"
}
Authentication Errorjson
{
  "error": "Invalid or revoked API key"
}
9

Webhooks

Webhook support for model completion notifications is planned for a future release. Currently, use polling on the status endpoint to check when models are ready.

Coming Soon

Webhook callbacks will send a POST request to your specified URL when model generation completes, eliminating the need for polling. This feature is on our roadmap.

10

Full Examples

Complete, copy-paste examples for common integration scenarios.

Generate a model and wait for completion

Bash — complete workflowbash
#!/bin/bash
API_KEY="YOUR_API_KEY"
BASE_URL="https://suntrace3d.com"

# 1. Request model generation
echo "Requesting model generation..."
RESPONSE=$(curl -s -X POST "$BASE_URL/api/v1/models" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"latitude": 44.8699, "longitude": 13.8420, "radiusKm": 0.3}')

MODEL_ID=$(echo $RESPONSE | jq -r '.id')
STATUS=$(echo $RESPONSE | jq -r '.status')
echo "Model ID: $MODEL_ID (status: $STATUS)"

# 2. Poll until ready
while [ "$STATUS" != "ready" ] && [ "$STATUS" != "failed" ]; do
  sleep 5
  RESPONSE=$(curl -s "$BASE_URL/api/v1/models/$MODEL_ID" \
    -H "Authorization: Bearer $API_KEY")
  STATUS=$(echo $RESPONSE | jq -r '.status')
  PROGRESS=$(echo $RESPONSE | jq -r '.progress // 0')
  echo "Status: $STATUS ($PROGRESS%)"
done

# 3. Get the model URL
if [ "$STATUS" = "ready" ]; then
  MODEL_URL=$(echo $RESPONSE | jq -r '.modelUrl')
  echo "Model ready: $MODEL_URL"
else
  echo "Generation failed"
fi

JavaScript/Node.js integration

Node.js — generate and polljavascript
const API_KEY = 'YOUR_API_KEY';
const BASE_URL = 'https://suntrace3d.com';

async function generateModel(lat, lng) {
  // 1. Request generation
  const res = await fetch(`${BASE_URL}/api/v1/models`, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${API_KEY}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ latitude: lat, longitude: lng }),
  });

  const { id, status, modelUrl } = await res.json();

  // If already cached, return immediately
  if (status === 'ready') return { id, modelUrl };

  // 2. Poll until ready
  return pollStatus(id);
}

async function pollStatus(modelId) {
  while (true) {
    await new Promise(r => setTimeout(r, 5000)); // Wait 5s

    const res = await fetch(`${BASE_URL}/api/v1/models/${modelId}`, {
      headers: { 'Authorization': `Bearer ${API_KEY}` },
    });

    const data = await res.json();
    console.log(`Status: ${data.status} (${data.progress || 0}%)`);

    if (data.status === 'ready') return data;
    if (data.status === 'failed') throw new Error('Generation failed');
  }
}

// Usage
generateModel(44.8699, 13.8420)
  .then(data => console.log('Model URL:', data.modelUrl))
  .catch(err => console.error(err));

Python integration

Python — generate and calculate solarpython
import requests
import time

API_KEY = "YOUR_API_KEY"
BASE_URL = "https://suntrace3d.com"

def generate_model(lat: float, lng: float) -> dict:
    """Generate an HD 3D model and wait for completion."""
    # Request generation
    res = requests.post(
        f"{BASE_URL}/api/v1/models",
        headers={"Authorization": f"Bearer {API_KEY}"},
        json={"latitude": lat, "longitude": lng, "radiusKm": 0.3},
    )
    data = res.json()

    if data["status"] == "ready":
        return data

    # Poll until ready
    model_id = data["id"]
    while True:
        time.sleep(5)
        res = requests.get(
            f"{BASE_URL}/api/v1/models/{model_id}",
            headers={"Authorization": f"Bearer {API_KEY}"},
        )
        data = res.json()
        print(f"Status: {data['status']} ({data.get('progress', 0)}%)")

        if data["status"] == "ready":
            return data
        if data["status"] == "failed":
            raise Exception("Generation failed")

def calculate_solar(lat: float, lng: float, tilt: float = 35, azimuth: float = 180) -> dict:
    """Calculate solar energy yield for a panel configuration."""
    res = requests.post(
        f"{BASE_URL}/api/solar/calculate",
        json={
            "latitude": lat,
            "longitude": lng,
            "tiltDeg": tilt,
            "azimuthDeg": azimuth,
            "panelAreaM2": 20,
            "panelEfficiency": 0.20,
        },
    )
    return res.json()

# Usage
model = generate_model(44.8699, 13.8420)
print(f"Model URL: {model['modelUrl']}")

solar = calculate_solar(44.8699, 13.8420)
print(f"Annual yield: {solar['annualYieldKwh']} kWh")
print(f"Monthly: {solar['monthlyKwh']}")
API integration code examples in multiple languages
Complete code examples in Bash, JavaScript, and Python for API integration

New to SunTrace3D?

Check out the User Guide for a complete walkthrough of the 3D viewer, shadow simulation, and solar panel analysis features.

User Guide