SunTrace3D 파트너 API를 사용하여 HD 3D 도시 모델을 생성하고, 태양광 에너지 수확량을 계산하며, 웹사이트에 인터랙티브 3D 뷰어를 임베드할 수 있습니다. 모든 엔드포인트는 JSON과 표준 HTTP 메서드를 사용합니다.
Markdown으로 보기 (기계 판독 가능)SunTrace3D API는 3D 도시 모델 생성과 태양광 에너지 계산에 대한 프로그래밍 방식 접근을 제공하는 RESTful 서비스입니다. API는 태양광 분석을 자체 애플리케이션, 웹사이트, 워크플로우에 통합하려는 파트너를 위해 설계되었습니다.
https://suntrace3d.com/api/v1/api/v1/models새 HD 3D 모델 생성/api/v1/models/:id모델 생성 상태 확인/api/solar/calculate태양광 에너지 수확량 계산/embed임베드 가능한 3D 뷰어 (iframe)/api/health헬스 체크 (인증 불필요)
모든 API 요청은 Authorization 헤더의 Bearer 토큰을 통한 인증이 필요합니다. API 키는 파트너 포털에서 관리됩니다.
curl -H "Authorization: Bearer st_live_abc123def456..." \
https://suntrace3d.com/api/v1/models클라이언트 사이드 JavaScript, 공개 리포지토리, 프론트엔드 코드에 API 키를 노출하지 마세요. 키가 유출된 경우 파트너 포털에서 즉시 해지하고 새 키를 생성하세요.
특정 지리적 위치의 HD 3D 도시 모델 생성을 요청합니다. 모델은 비동기적으로 생성됩니다 — 상태 엔드포인트를 폴링하여 준비 완료를 확인하세요.
/api/v1/modelslatitudenumberrequired중심점의 위도 (-90 ~ 90)longitudenumberrequired중심점의 경도 (-180 ~ 180)radiusKmnumber모델링할 영역의 반경 (km) (기본값: 0.3)idstringrequired상태 폴링을 위한 고유 모델 식별자statusstringrequired"pending" | "processing" | "ready" | "failed"modelUrlstringGLB 모델 파일 URL (준비 완료 시)progressnumber생성 진행률 0-100 (처리 중일 때)stepstring현재 생성 단계 설명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
}'{
"id": "hd_44.8699_13.8420_0.3",
"status": "pending"
}{
"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"
}동일한 위치와 반경의 모델이 이미 생성된 경우, API는 캐시된 결과를 status: "ready"로 즉시 반환합니다. 모델은 S3에 30일간 캐시됩니다. 캐시된 결과에는 요금이 부과되지 않습니다.

이 엔드포인트를 폴링하여 모델 생성 요청의 상태를 확인하세요. 모델은 pending → processing → ready 단계를 거칩니다.
/api/v1/models/:idcurl https://suntrace3d.com/api/v1/models/hd_44.8699_13.8420_0.3 \
-H "Authorization: Bearer YOUR_API_KEY"{
"id": "hd_44.8699_13.8420_0.3",
"status": "processing",
"progress": 65,
"step": "Generating textures..."
}{
"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
}5-10초마다 폴링하는 것을 권장합니다. 일반적인 생성 시간은 영역 크기와 서버 부하에 따라 30-120초입니다. progress 필드는 UI에 진행률 표시기를 표시하기 위한 백분율(0-100)을 제공합니다.
특정 패널 구성과 위치에 대한 연간 태양광 에너지 수확량을 계산합니다. 이 엔드포인트는 정확한 일사량 값을 위해 PVGIS(태양광발전 지리정보 시스템) 위성 데이터를 사용합니다.
/api/solar/calculatelatitudenumberrequired위치 위도longitudenumberrequired위치 경도tiltDegnumberrequired패널 경사각 (도) (0-90)azimuthDegnumberrequired패널 방위각 (도) (0=북, 180=남)panelAreaM2numberrequired패널 총 면적 (제곱미터)panelEfficiencynumberrequired패널 효율 (0.0 - 1.0, 보통 0.18-0.22)shadingLossFractionnumber차폐 손실 계수 (0.0-1.0, 기본값: 0)annualYieldKwhnumberrequired추정 연간 에너지 수확량 (kWh)peakPowerKwnumberrequired피크 출력 (kW)specificYieldnumberrequired비에너지 수확량 (kWh/kWp)monthlyKwhnumber[]required12개월 월간 kWh 값 배열sourcestringrequired데이터 소스 식별자 ("pvgis")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
}'{
"annualYieldKwh": 4982,
"peakPowerKw": 4.0,
"specificYield": 1246,
"monthlyKwh": [248, 305, 412, 465, 522, 548, 562, 530, 445, 368, 280, 232],
"source": "pvgis"
}태양광 계산 엔드포인트는 공개적으로 사용 가능하며 API 키가 필요하지 않습니다. 유럽위원회의 공동연구센터가 관리하는 PVGIS 공개 API를 사용합니다.

iframe을 사용하여 웹사이트에 인터랙티브 3D 태양광 뷰어를 임베드하세요. 임베드 뷰어에는 그림자 시뮬레이션용 시간 컨트롤이 포함되어 있으며 데스크톱과 모바일 모두에서 작동합니다.
latnumberrequired표시할 위치의 위도lngnumberrequired표시할 위치의 경도keystringrequired인증용 API 키<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><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>
API는 공정한 사용과 시스템 안정성을 보장하기 위해 속도 제한을 적용합니다.
{
"error": "Rate limit exceeded. Maximum 10 generations per hour."
}API는 표준 HTTP 상태 코드를 사용합니다. 모든 오류 응답에는 문제를 설명하는 error 필드가 포함된 JSON 본문이 있습니다.
{
"error": "latitude and longitude are required"
}{
"error": "Invalid or revoked API key"
}모델 완료 알림을 위한 Webhook 지원은 향후 릴리스에 계획되어 있습니다. 현재는 상태 엔드포인트 폴링을 사용하여 모델 준비 완료를 확인하세요.
Webhook 콜백은 모델 생성이 완료되면 지정된 URL로 POST 요청을 보내 폴링의 필요성을 제거합니다. 이 기능은 로드맵에 포함되어 있습니다.
일반적인 통합 시나리오를 위한 완전한 복사-붙여넣기 예제입니다.
#!/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"
ficonst 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));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']}")