メインコンテンツへスキップ

ヘルプセンター

エンドポイント詳細リファレンス

最終更新: 2024/1/17
apiendpointsreferencehttprestdocumentation
エンドポイント詳細リファレンス 築古不動産投資シミュレーターAPIの全エンドポイントを網羅した技術仕様書です。各エンドポイントの詳細な仕様、リクエスト・レスポンス例、エラーハンドリング、実装のベストプラクティスを詳しく解説します。 📋 API仕様概要 Base URL: https://kominka-apart-sim.vercel.app/api Protocol: HTTPS only (TLS 1.2+) Authentication: Bearer Token (JWT) Content-Type: application/json Charset: UTF-8 Rate Limiting: 1000 requests/hour 🔐 認証エンドポイント POST /auth/oauth/token 説明: OAuth認証でアクセストークンを取得 リクエスト POST /auth/oauth/token Content-Type: application/x-www-form-urlencoded grant_type=authorization_code& code=AUTHORIZATION_CODE& client_id=YOUR_CLIENT_ID& client_secret=YOUR_CLIENT_SECRET& redirect_uri=https://your-app.com/callback レスポンス (200 OK) { "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IjIwMjQtMDEifQ...", "token_type": "Bearer", "expires_in": 3600, "refresh_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IjIwMjQtMDEifQ...", "scope": "read:simulations write:simulations delete:simulations", "user_id": "123e4567-e89b-12d3-a456-426614174000" } エラーレスポンス (400 Bad Request) { "error": "invalid_grant", "error_description": "認証コードが無効または期限切れです", "error_uri": "https://kominka-apart-sim.vercel.app/docs/errors#invalid_grant" } POST /auth/oauth/refresh 説明: リフレッシュトークンを使用してアクセストークンを更新 リクエスト POST /auth/oauth/refresh Content-Type: application/json Authorization: Bearer CURRENT_ACCESS_TOKEN { "refresh_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IjIwMjQtMDEifQ..." } レスポンス (200 OK) { "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IjIwMjQtMDEifQ...", "token_type": "Bearer", "expires_in": 3600, "scope": "read:simulations write:simulations delete:simulations" } 👤 ユーザー管理エンドポイント GET /users/me 説明: 現在のユーザー情報を取得 リクエスト GET /users/me Authorization: Bearer ACCESS_TOKEN レスポンス (200 OK) { "id": "123e4567-e89b-12d3-a456-426614174000", "email": "user@example.com", "name": "田中太郎", "avatar_url": "https://example.com/avatar.jpg", "plan": "premium", "created_at": "2024-01-01T00:00:00Z", "updated_at": "2024-01-17T10:30:00Z", "preferences": { "currency": "JPY", "language": "ja", "timezone": "Asia/Tokyo", "email_notifications": true }, "usage": { "simulations_count": 15, "calculations_count": 245, "api_calls_this_month": 1250, "storage_used_mb": 2.5 } } 📊 シミュレーション管理エンドポイント GET /simulations 説明: ユーザーのシミュレーション一覧を取得 クエリパラメータ パラメータ 型 説明 デフォルト page integer ページ番号 1 limit integer 取得件数 (max: 100) 20 sort string ソート項目 created_at order string ソート順 (asc/desc) desc property_type string 物件種別フィルター - search string タイトル検索 - リクエスト例 GET /simulations?page=1&limit=10&sort=updated_at&order=desc&property_type=house Authorization: Bearer ACCESS_TOKEN レスポンス (200 OK) { "simulations": [ { "id": "123e4567-e89b-12d3-a456-426614174000", "title": "築30年木造戸建て投資", "property_type": "house", "property_price": 8000000, "land_price": 3000000, "building_price": 5000000, "annual_rent": 960000, "created_at": "2024-01-15T10:30:00Z", "updated_at": "2024-01-16T14:20:00Z", "share_code": "abc123def456", "is_public": false, "results": { "gross_yield": 12.0, "net_yield": 9.12, "monthly_cash_flow": 35200, "annual_cash_flow": 422400, "roi": 18.72, "npv": 1850000, "irr": 16.8, "payback_period": 5.3 }, "tags": ["高利回り", "築古", "戸建て"] } ], "pagination": { "page": 1, "limit": 10, "total": 25, "total_pages": 3, "has_next": true, "has_prev": false }, "filters": { "property_type": "house", "applied_filters": 1 } } POST /simulations 説明: 新しいシミュレーションを作成 リクエストボディ POST /simulations Content-Type: application/json Authorization: Bearer ACCESS_TOKEN { "title": "築25年RC造アパート投資", "property_type": "apartment", "property_price": 25000000, "land_price": 10000000, "building_price": 15000000, "annual_rent": 3600000, "vacancy_rate": 8, "expense_rate": 25, "renovation_cost": 2000000, "broker_fee_rate": 3, "use_loan": true, "loan_amount": 20000000, "loan_interest_rate": 2.8, "loan_term": 30, "loan_type": "fixed", "is_old_property": true, "building_age": 25, "structure_type": "rc", "depreciation_method": "straight_line", "building_ratio": 60, "discount_rate": 5, "holding_period": 10, "exit_cap_rate": 8, "prepayment_plans": [ { "year": 3, "amount": 5000000, "source": "cash_flow" } ], "tags": ["アパート", "RC造", "築古"], "memo": "駅から徒歩8分、周辺開発予定あり", "is_public": false } レスポンス (201 Created) { "id": "789e0123-e89b-12d3-a456-426614174000", "title": "築25年RC造アパート投資", "created_at": "2024-01-17T11:00:00Z", "share_code": "xyz789abc123", "results": { "gross_yield": 14.4, "net_yield": 10.8, "monthly_cash_flow": 125000, "annual_cash_flow": 1500000, "roi": 30.0, "npv": 8450000, "irr": 22.5, "payback_period": 3.3, "depreciation": { "annual_amount": 1363636, "remaining_years": 22, "total_depreciation": 30000000 }, "tax_simulation": { "personal_income_tax": 225000, "corporate_tax": 135000, "tax_savings": 90000 }, "sensitivity_analysis": { "rent_impact": { "-10%": { "roi": 21.0, "npv": 6800000 }, "+10%": { "roi": 39.0, "npv": 10100000 } }, "vacancy_impact": { "5%": { "roi": 27.5, "npv": 7650000 }, "15%": { "roi": 22.5, "npv": 5250000 } } } } } GET /simulations/{id} 説明: 特定のシミュレーション詳細を取得 パスパラメータ id: シミュレーションID (UUID) クエリパラメータ include: 含める関連データ (cash_flow, sensitivity, stress_test) リクエスト例 GET /simulations/123e4567-e89b-12d3-a456-426614174000?include=cash_flow,sensitivity Authorization: Bearer ACCESS_TOKEN レスポンス (200 OK) { "id": "123e4567-e89b-12d3-a456-426614174000", "title": "築30年木造戸建て投資", "property_type": "house", "property_price": 8000000, "land_price": 3000000, "building_price": 5000000, "annual_rent": 960000, "vacancy_rate": 5, "expense_rate": 20, "created_at": "2024-01-15T10:30:00Z", "updated_at": "2024-01-16T14:20:00Z", "user_id": "user123", "share_code": "abc123def456", "is_public": false, "results": { "basic_metrics": { "gross_yield": 12.0, "net_yield": 9.12, "monthly_cash_flow": 35200, "annual_cash_flow": 422400, "roi": 18.72, "total_initial_cost": 2400000 }, "advanced_metrics": { "npv": 1850000, "irr": 16.8, "payback_period": 5.3, "profitability_index": 1.77, "break_even_vacancy_rate": 15.2 }, "cash_flow_projection": [ { "year": 1, "rental_income": 912000, "operating_expenses": 182400, "loan_payment": 384000, "depreciation": 1136364, "taxable_income": -790764, "net_cash_flow": 345600, "cumulative_cash_flow": 345600 }, { "year": 2, "rental_income": 912000, "operating_expenses": 182400, "loan_payment": 384000, "depreciation": 1136364, "taxable_income": -790764, "net_cash_flow": 345600, "cumulative_cash_flow": 691200 } ], "sensitivity_analysis": { "tornado_chart": [ { "parameter": "annual_rent", "impact_range": { "min": -3.2, "max": 3.2 }, "sensitivity_score": 0.85 }, { "parameter": "vacancy_rate", "impact_range": { "min": -2.1, "max": 0 }, "sensitivity_score": 0.65 } ], "heatmap": { "rent_vs_vacancy": [ { "rent_change": -20, "vacancy_rate": 0, "net_yield": 5.1 }, { "rent_change": -20, "vacancy_rate": 10, "net_yield": 3.8 }, { "rent_change": 0, "vacancy_rate": 0, "net_yield": 9.1 }, { "rent_change": 20, "vacancy_rate": 0, "net_yield": 13.1 } ] } } }, "tags": ["高利回り", "築古", "戸建て"], "memo": "駅徒歩12分、商業施設近く" } 🔢 計算エンドポイント POST /calculations/realtime 説明: リアルタイム計算(保存なし) リクエストボディ POST /calculations/realtime Content-Type: application/json Authorization: Bearer ACCESS_TOKEN { "property_price": 8000000, "annual_rent": 960000, "vacancy_rate": 5, "expense_rate": 20, "use_loan": true, "loan_amount": 6000000, "loan_interest_rate": 2.5, "loan_term": 25, "calculate_advanced": true, "calculate_depreciation": true, "calculate_tax": true } レスポンス (200 OK) { "calculation_id": "calc_789xyz123", "timestamp": "2024-01-17T11:30:00Z", "execution_time_ms": 45, "results": { "basic_metrics": { "gross_yield": 12.0, "net_yield": 8.64, "monthly_cash_flow": 31200, "annual_cash_flow": 374400, "roi": 18.72, "total_initial_cost": 2000000, "monthly_loan_payment": 26847 }, "advanced_metrics": { "npv": 1456000, "irr": 15.2, "payback_period": 5.8, "profitability_index": 1.73, "break_even_vacancy_rate": 12.8 }, "depreciation": { "annual_amount": 1136364, "method": "straight_line", "remaining_years": 4, "total_depreciation": 4545456 }, "tax_calculation": { "taxable_income": -761964, "personal_income_tax": 0, "corporate_tax": 0, "effective_tax_rate": 0, "tax_savings": 152393 } } } 📈 分析エンドポイント POST /simulations/{id}/sensitivity-analysis 説明: 感度分析を実行 リクエストボディ POST /simulations/123e4567-e89b-12d3-a456-426614174000/sensitivity-analysis Content-Type: application/json Authorization: Bearer ACCESS_TOKEN { "parameters": [ { "name": "annual_rent", "range": { "min": -30, "max": 30, "step": 5 }, "unit": "percent" }, { "name": "vacancy_rate", "range": { "min": 0, "max": 25, "step": 2.5 }, "unit": "percent" }, { "name": "expense_rate", "range": { "min": 15, "max": 35, "step": 2.5 }, "unit": "percent" }, { "name": "loan_interest_rate", "range": { "min": 1.0, "max": 5.0, "step": 0.25 }, "unit": "percent" } ], "target_metrics": ["net_yield", "roi", "npv", "irr"], "confidence_level": 95, "monte_carlo_runs": 10000 } レスポンス (200 OK) { "analysis_id": "sens_456def789", "simulation_id": "123e4567-e89b-12d3-a456-426614174000", "created_at": "2024-01-17T12:00:00Z", "execution_time_ms": 1250, "results": { "tornado_chart": [ { "parameter": "annual_rent", "parameter_label": "年間家賃収入", "base_value": 960000, "impact_on_roi": { "min": -8.5, "max": 8.5, "range": 17.0 }, "impact_on_npv": { "min": -850000, "max": 850000, "range": 1700000 }, "sensitivity_score": 0.92, "rank": 1 }, { "parameter": "loan_interest_rate", "parameter_label": "ローン金利", "base_value": 2.5, "impact_on_roi": { "min": -4.2, "max": 6.8, "range": 11.0 }, "impact_on_npv": { "min": -420000, "max": 680000, "range": 1100000 }, "sensitivity_score": 0.73, "rank": 2 } ], "heatmap_data": { "rent_vs_vacancy": [ { "x": -20, "y": 0, "net_yield": 5.8, "roi": 8.1, "npv": 650000, "color_intensity": 0.3 }, { "x": 0, "y": 5, "net_yield": 8.6, "roi": 17.2, "npv": 1450000, "color_intensity": 0.7 } ] }, "monte_carlo": { "statistics": { "roi": { "mean": 18.72, "std_dev": 5.43, "min": 2.1, "max": 35.8, "percentiles": { "5": 9.8, "25": 15.2, "50": 18.7, "75": 22.5, "95": 28.1 } }, "npv": { "mean": 1856000, "std_dev": 845000, "min": -450000, "max": 4200000, "percentiles": { "5": 520000, "25": 1250000, "50": 1850000, "75": 2450000, "95": 3200000 } } }, "risk_metrics": { "probability_of_loss": 0.08, "expected_shortfall": -125000, "sharpe_ratio": 2.45, "value_at_risk_95": 520000 } } } } 🔍 検索エンドポイント GET /search/simulations 説明: 高度な検索機能でシミュレーションを検索 クエリパラメータ q: 検索キーワード property_type: 物件種別 (house, apartment) price_min: 物件価格の下限 price_max: 物件価格の上限 yield_min: 利回りの下限 yield_max: 利回りの上限 roi_min: ROIの下限 building_age_max: 築年数の上限 tags: タグ(カンマ区切り) sort: ソート項目 order: ソート順 リクエスト例 GET /search/simulations?q=戸建て&property_type=house&price_min=5000000&price_max=12000000&yield_min=10&roi_min=15&tags=高利回り,築古 Authorization: Bearer ACCESS_TOKEN レスポンス (200 OK) { "query": { "keyword": "戸建て", "filters": { "property_type": "house", "price_range": [5000000, 12000000], "yield_min": 10, "roi_min": 15, "tags": ["高利回り", "築古"] } }, "results": [ { "id": "123e4567-e89b-12d3-a456-426614174000", "title": "築30年木造戸建て投資", "relevance_score": 0.92, "matched_fields": ["title", "tags", "memo"], "highlight": { "title": "築30年木造戸建て投資", "tags": ["高利回り", "築古", "戸建て"] }, "property_type": "house", "property_price": 8000000, "results": { "gross_yield": 12.0, "net_yield": 9.12, "roi": 18.72 }, "created_at": "2024-01-15T10:30:00Z" } ], "aggregations": { "property_type": { "house": 12, "apartment": 8 }, "price_ranges": { "5000000-8000000": 5, "8000000-12000000": 10, "12000000-15000000": 5 }, "yield_ranges": { "10-12": 8, "12-15": 7, "15+": 5 } }, "pagination": { "page": 1, "limit": 20, "total": 20, "total_pages": 1 } } ❌ エラーレスポンス詳細 🚨 標準エラー形式 バリデーションエラー (400 Bad Request) { "error": { "code": "VALIDATION_ERROR", "message": "入力値が無効です", "details": [ { "field": "property_price", "message": "物件価格は100万円以上である必要があります", "received": 500000, "expected": "≥ 1000000" }, { "field": "annual_rent", "message": "年間家賃収入は必須です", "received": null, "expected": "number > 0" } ] }, "request_id": "req_123abc456def", "timestamp": "2024-01-17T12:30:00Z" } 認証エラー (401 Unauthorized) { "error": { "code": "AUTHENTICATION_REQUIRED", "message": "認証が必要です", "details": [ { "field": "authorization", "message": "有効なBearerトークンが必要です" } ] }, "request_id": "req_789def123abc", "timestamp": "2024-01-17T12:30:00Z" } 権限エラー (403 Forbidden) { "error": { "code": "INSUFFICIENT_PERMISSIONS", "message": "このリソースにアクセスする権限がありません", "details": [ { "field": "simulation_id", "message": "他のユーザーのシミュレーションにはアクセスできません", "required_permission": "read:own_simulations" } ] }, "request_id": "req_456ghi789jkl", "timestamp": "2024-01-17T12:30:00Z" } レート制限エラー (429 Too Many Requests) { "error": { "code": "RATE_LIMIT_EXCEEDED", "message": "レート制限に達しました", "details": [ { "field": "rate_limit", "message": "1時間あたり1000リクエストの制限を超えました", "limit": 1000, "remaining": 0, "reset_at": "2024-01-17T13:00:00Z" } ] }, "request_id": "req_789mno123pqr", "timestamp": "2024-01-17T12:30:00Z" } 📊 レスポンスヘッダー 標準ヘッダー HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 X-Request-ID: req_123abc456def X-Response-Time: 45ms X-RateLimit-Limit: 1000 X-RateLimit-Remaining: 995 X-RateLimit-Reset: 1642694400 X-API-Version: v1 Cache-Control: no-cache, no-store, must-revalidate Pragma: no-cache Expires: 0 CORS ヘッダー Access-Control-Allow-Origin: https://your-domain.com Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS Access-Control-Allow-Headers: Authorization, Content-Type, X-API-Key Access-Control-Allow-Credentials: true Access-Control-Max-Age: 86400 🔄 ページネーション ページネーション仕様 一覧系エンドポイントでは、一貫したページネーション形式を使用します。 標準ページネーション形式 { "data": [...], "pagination": { "page": 2, "limit": 20, "total": 157, "total_pages": 8, "has_next": true, "has_prev": true, "next_page": 3, "prev_page": 1 }, "links": { "first": "/api/simulations?page=1&limit=20", "prev": "/api/simulations?page=1&limit=20", "next": "/api/simulations?page=3&limit=20", "last": "/api/simulations?page=8&limit=20" } } 📝 実装のベストプラクティス 🎯 効率的なAPI利用 1. 適切なHTTPメソッドの使用 GET: データの取得(副作用なし) POST: データの作成・複雑な操作 PUT: データの完全更新 PATCH: データの部分更新 DELETE: データの削除 2. 効率的なデータ取得 フィールド選択: ?fields=id,title,results.roi 関連データ: ?include=cash_flow,sensitivity 適切な制限: ?limit=50 (デフォルト: 20, 最大: 100) 3. エラーハンドリング async function apiCall(endpoint, options) { try { const response = await fetch(endpoint, options); // レート制限チェック if (response.status === 429) { const retryAfter = response.headers.get('Retry-After'); throw new Error(`レート制限。${retryAfter}秒後に再試行してください。`); } // 認証エラー if (response.status === 401) { await refreshToken(); return apiCall(endpoint, options); // 再試行 } const data = await response.json(); if (!response.ok) { throw new Error(data.error.message || '不明なエラー'); } return data; } catch (error) { throw error; } } 🔗 関連リンク MCP Server完全セットアップガイド API認証・セキュリティガイド API完全ガイド HTTPステータスコード HTTP/1.1 仕様

この記事は役に立ちましたか?