Weston API
Start an analysis, poll for the final report, and recompute completed runs with user overrides from your own backend. API keys are for trusted server-side code only.
API Keys
Create named keys for production services, automations, and partner integrations. Full secrets are shown once at generation time.
Recent Usage
Only completed analyses started with a Weston API key appear here. Logged-in frontend runs are excluded from this table.
Authentication
Direct API callers must use a Weston API key as a bearer token. Every endpoint documented here requires authentication and returns 401 for missing, invalid, or revoked credentials.
Authorization: Bearer wk_live_...Photo Upload Intents
Create signed upload URLs before starting an analysis, upload each file with the returned method and headers, then pass the returned asset objects in inputs.photos or inputs.floor_plan_image.
| POST | /api/co-living/photo-assets/upload-intents |
{
"files": [
{
"filename": "front.jpg",
"content_type": "image/jpeg",
"size_bytes": 1234567,
"source": "uploaded",
"caption": "Front exterior"
}
]
}{
"uploads": [
{
"upload_url": "https://storage.example/signed-put-url",
"method": "PUT",
"headers": {
"Content-Type": "image/jpeg"
},
"asset": {
"asset_id": "f8751c49-cc99-4215-95fc-f3891250c2d0",
"source": "uploaded",
"gcs_uri": "gs://bucket/photo_assets/co-living/user/batch/photo.jpg",
"object_name": "photo_assets/co-living/user/batch/photo.jpg",
"url": "https://storage.example/signed-read-url",
"content_type": "image/jpeg",
"caption": "Front exterior",
"width": null,
"height": null
}
}
]
}Portfolio And Usage
Fetch portfolio rows and quota details for the authenticated Weston user.
| Method | Endpoint | Purpose |
|---|---|---|
| GET | /api/portfolio | List all portfolio deals for the authenticated user. |
| PATCH | /api/portfolio/{deal_id} | Mark an error panel dismissed with { error_dismissed: true }. |
| DELETE | /api/portfolio/{deal_id} | Archive a portfolio deal. |
| GET | /api/usage | Fetch report quota, remaining credits, reservations, and usage events for the authenticated user. |
curl https://YOUR_DOMAIN/api/portfolio \
-H "Authorization: Bearer wk_live_..."{
"deals": [
{
"id": "2f3f2d9f-08f6-4f5f-b9f2-5d2e7c9f70d1",
"strategy": "co-living",
"property_address": "123 Main St, Atlanta, GA",
"listing_url": "https://example.com/listing",
"status": "done",
"analysis_slug": "atlanta-main-st-coliving",
"created_at": "2026-05-14T12:00:00Z",
"updated_at": "2026-05-14T12:06:00Z",
"archived": false,
"error_dismissed": false,
"analysis_error": null,
"failure_code": null
}
],
"summary": {
"total": 1,
"by_strategy": {
"co-living": 1
},
"by_status": {
"done": 1
}
}
}curl https://YOUR_DOMAIN/api/usage \
-H "Authorization: Bearer wk_live_..."{
"quota": {
"report_quota": 100,
"reports_used": 26,
"active_reservations": 1,
"reports_remaining": 73
},
"reservations": {
"total": 27,
"reserved": 1,
"consumed": 26,
"released": 0
},
"usage": {
"total_events": 26,
"completed_analyses": 26,
"by_strategy": {
"co-living": 26
},
"by_route": {
"analyze": 26
}
},
"events": []
}reports_remaining is computed from the configured quota minus completed analyses and active reservations. null means the account has unlimited report credits. Usage events contain completed analyses only; polls, denied calls, overrides, and failed runs are excluded from billable usage history.Quickstart
Run a co-living analysis when you need conversion feasibility, room revenue, project costs, and strategy-level outcomes.
Quickstart
Send a bearer API key, start an async run, then poll the run id until the status is terminal.
- Create a keyName it after the backend or workflow that will start co-living analyses.
- Start preflightPOST the property, listing URL, photos, optional floor plan, and analysis_tier. Omit analysis_tier for the default Pro run.
- Review the propertyPoll the deal until status is review or onboarding, then inspect property_summary.
- Complete underwritingPOST the reviewed assumptions to the complete endpoint; the original start already reserved the report credit.
- Follow upUse scenarios, explain-metric, assumptions, versions, messages, or the dashboard URL after status is done.
curl -X POST https://YOUR_DOMAIN/api/co-living/analyze \
-H "Authorization: Bearer wk_live_..." \
-H "Content-Type: application/json" \
-d '{
"property": {
"address": "123 Main St, Atlanta, GA",
"listing_url": "https://example.com/listing"
},
"analysis_tier": "pro",
"inputs": {
"photos": [
{ "url": "https://example.com/kitchen.jpg" }
],
"floor_plan_image": null,
"preferences": {
"aggressiveness": "max_viable",
"optimize_for": "revenue",
"target_market_segment": "workforce"
},
"user_overrides": {},
"buy_box": {
"cash_flow_threshold": 500,
"cash_on_cash_threshold": 0.07
}
},
"metadata": {
"client_reference_id": "coliving-lead-77"
}
}'Endpoints
Use these endpoints for co-living analysis lifecycle operations.
| Method | Endpoint | Purpose |
|---|---|---|
| POST | /api/co-living/analyze | Start a coliving_v2 deal. analysis_tier defaults to pro; pass flash for a Flash run. The public run_id is the v2 deal slug. |
| GET | /api/co-living/analyze/{run_id} | Fetch status or final result. Add ?status_only=true for a lightweight status envelope. |
| POST | /api/co-living/analyze/{run_id}/complete | Confirm reviewed property details and run full underwriting. |
| GET | /api/co-living/analyze/{run_id}/editable-fields | List dashboard-editable fields. Add scenario_id for scenario-specific fields. |
| GET | /api/co-living/analyze/{run_id}/scenarios | List available scenarios and active scenario metadata. |
| POST | /api/co-living/analyze/{run_id}/explain-metric | Explain a metric for the completed deal. |
| PATCH | /api/co-living/analyze/{run_id}/assumptions | Apply dashboard-style updates through the shared v2 tool. |
| POST | /api/co-living/analyze/{run_id}/scenarios | Create a custom scenario from a natural-language description. |
| POST | /api/co-living/analyze/{run_id}/messages | Enqueue a follow-up chat or agent turn for the existing deal. |
| GET | /api/co-living/analyze/{run_id}/jobs/{job_id} | Fetch durable job status plus the latest deal envelope. |
| GET | /api/co-living/analyze/{run_id}/jobs/{job_id}/events | Fetch incremental stream events. Add after_seq to resume. |
| POST | /api/co-living/photo-assets/upload-intents | Create signed upload URLs for photos and floor plans. |
| GET | /api/co-living/analyze/{run_id}/image?url=... | Proxy owned v2 deal/listing images through allow-list checks. |
| GET | /api/co-living/overrides/schema | List editable v2 path families and supported operations. |
| PATCH | /api/co-living/analyze/{run_id}/overrides | Apply one or many value edits with updates: [{ field_path, new_value, operation }]. |
| DELETE | /api/co-living/analyze/{run_id}/overrides | Clear all active v2 session and scenario overrides. |
| POST | /api/co-living/analyze/{run_id}/scenarios/{scenario_id}/activate | Switch the active scenario. |
| POST | /api/co-living/analyze/{run_id}/scenarios/replan | Replan scenarios after room, bedroom, or bath corrections. |
| POST | /api/co-living/analyze/{run_id}/rooms | Add rooms, optionally triggering scenario replanning. |
| DELETE | /api/co-living/analyze/{run_id}/rooms/{room_id} | Remove a room, optionally triggering scenario replanning. |
| GET | /api/co-living/analyze/{run_id}/versions | List v2 deal versions. |
| GET | /api/co-living/analyze/{run_id}/versions/{version_id} | Fetch one version and its snapshot. |
| POST | /api/co-living/analyze/{run_id}/versions/{version_id}/revert | Restore a historical v2 version and create a new current version. |
Start Request
Use property for address and listing context, analysis_tier for Pro or Flash, inputs for media and modeling preferences, and metadata for your own reference id. Missing analysis_tier defaults to pro.
{
"property": {
"address": "123 Main St, Atlanta, GA",
"listing_url": "https://example.com/listing"
},
"analysis_tier": "pro",
"inputs": {
"photos": [
{
"url": "https://example.com/kitchen.jpg"
}
],
"floor_plan_image": null,
"preferences": {
"aggressiveness": "max_viable",
"optimize_for": "revenue",
"target_market_segment": "workforce"
},
"user_overrides": {},
"buy_box": {
"cash_flow_threshold": 500,
"cash_on_cash_threshold": 0.07
}
},
"metadata": {
"client_reference_id": "coliving-lead-77"
}
}{
"run_id": "atlanta-main-st-coliving",
"strategy": "co-living",
"analysis_tier": "pro",
"status": "queued",
"job_id": "job_01JZ9A2Z9V0V2K8T7D3D5E6F7G",
"created_at": "2026-05-26T12:00:00Z",
"api_contract_version": "2026-05-31",
"poll_url": "/api/co-living/analyze/atlanta-main-st-coliving",
"dashboard_url": "/reports/co-living/atlanta-main-st-coliving",
"next_action": "Preflight is running (~2-3 min). Poll until status is review, then complete the analysis.",
"metadata": {
"api_contract_version": "2026-05-31",
"session_id": "sess_01JZ9A2YQW5G9T6A6S1ZZT4K7R",
"deal_slug": "atlanta-main-st-coliving",
"analysis_tier": "pro",
"dashboard_url": "/reports/co-living/atlanta-main-st-coliving",
"client_reference_id": "coliving-lead-77"
}
}Polling Responses
The co-living run moves from queued or running into review, onboarding, done, error, or not_suitable. Add ?status_only=true to omit data and overrides for lightweight status checks.
{
"run_id": "atlanta-main-st-coliving",
"strategy": "co-living",
"status": "review",
"next_action": "Property mapped. Review property_summary with the user, then call the complete endpoint to run full underwriting.",
"property": {
"address": "123 Main St, Atlanta, GA",
"listing_url": "https://example.com/listing"
},
"property_summary": {
"bedroom_count": 3,
"full_bathroom_count": 2,
"rooms": []
},
"data": {},
"overrides": {},
"error": {
"message": null,
"code": null
},
"metadata": {
"api_contract_version": "2026-05-31",
"status_values": [
"queued",
"running",
"review",
"onboarding",
"done",
"error",
"not_suitable"
],
"session_id": "sess_01JZ9A2YQW5G9T6A6S1ZZT4K7R",
"deal_slug": "atlanta-main-st-coliving",
"dashboard_url": "/reports/co-living/atlanta-main-st-coliving",
"client_reference_id": "coliving-lead-77",
"created_at": "2026-05-26T12:00:00Z",
"updated_at": "2026-05-26T12:01:00Z",
"completed_at": null,
"recomputed_at": null
}
}{
"run_id": "atlanta-main-st-coliving",
"strategy": "co-living",
"status": "done",
"next_action": "Analysis complete. Use explain, assumptions, scenarios, or versions endpoints for follow-ups.",
"property": {
"address": "123 Main St, Atlanta, GA",
"listing_url": "https://example.com/listing"
},
"data": {
"property_summary": {},
"scenario_set": {},
"deal_analysis": {},
"recommendation_summary": {},
"v2_analysis_result": {}
},
"v2_analysis_result": {},
"recommended_scenario_id": "baseline",
"overrides": {},
"report_version": {
"id": "fb9d7e8c-8ec1-4b98-bf62-13f089df8a21",
"version_number": 1,
"created_at": "2026-05-26T12:08:00Z",
"history_url": "/api/co-living/analyze/atlanta-main-st-coliving/versions"
},
"error": {
"message": null,
"code": null
},
"metadata": {
"api_contract_version": "2026-05-31",
"status_values": [
"queued",
"running",
"review",
"onboarding",
"done",
"error",
"not_suitable"
],
"session_id": "sess_01JZ9A2YQW5G9T6A6S1ZZT4K7R",
"deal_slug": "atlanta-main-st-coliving",
"dashboard_url": "/reports/co-living/atlanta-main-st-coliving",
"client_reference_id": "coliving-lead-77",
"created_at": "2026-05-26T12:00:00Z",
"updated_at": "2026-05-26T12:08:00Z",
"completed_at": "2026-05-26T12:08:00Z",
"recomputed_at": null,
"report_version_number": 1
}
}{
"run_id": "atlanta-main-st-coliving",
"strategy": "co-living",
"status": "not_suitable",
"property": {
"address": "123 Main St, Atlanta, GA",
"listing_url": "https://example.com/listing"
},
"data": null,
"overrides": {},
"error": {
"message": "This property is not suitable for co-living conversion.",
"code": "unsupported_property_type"
},
"metadata": {
"api_contract_version": "2026-05-31",
"status_values": [
"queued",
"running",
"review",
"onboarding",
"done",
"error",
"not_suitable"
],
"session_id": "sess_01JZ9A2YQW5G9T6A6S1ZZT4K7R",
"deal_slug": "atlanta-main-st-coliving",
"dashboard_url": "/reports/co-living/atlanta-main-st-coliving",
"client_reference_id": "coliving-lead-77",
"created_at": "2026-05-26T12:00:00Z",
"updated_at": "2026-05-26T12:04:00Z",
"completed_at": null,
"recomputed_at": null
}
}run_id is the v2 deal slug. Responses also include metadata.session_id, metadata.dashboard_url, and next_action. GET /api/co-living/analyze/{run_id}/report.pdf returns 410 Gone.Complete And Follow Up
These endpoints are REST aliases over the same coliving_v2 tool routes used by MCP, email, WhatsApp, and the dashboard.
{
"property_summary_patches": {
"bedroom_count": 4
},
"property_inputs": {
"purchase_price": 700000,
"insurance_annual": 1800
},
"target_bedroom_count": 4,
"scenario_generation_mode": "explore_and_recommend",
"package_selections": {},
"financing_preferences": {},
"operating_assumptions": {}
}GET /api/co-living/analyze/{run_id}/editable-fields?scenario_id=baseline
GET /api/co-living/analyze/{run_id}/scenarios
POST /api/co-living/analyze/{run_id}/explain-metric
{
"metric_id": "cash_on_cash_pct",
"scenario_id": "baseline",
"question": "Why did this change?"
}
PATCH /api/co-living/analyze/{run_id}/assumptions
{
"updates": [
{
"field_path": "operating.occupancy_rate_pct",
"new_value": 91
}
],
"rationale": "Operator expects a stabilized lease-up."
}
POST /api/co-living/analyze/{run_id}/scenarios
{
"description": "Convert the office into a compliant bedroom and compare yield.",
"base_scenario_id": "baseline",
"target_bedroom_count": 4
}/assumptions is the dashboard-style edit path; /overrides remains available for low-level path patches.Low-level Overrides
Co-living v2 overrides apply path-level edits without consuming report credits. Prefer /assumptions for dashboard-style updates.
{
"updates": [
{
"field_path": "financing.purchase_price",
"new_value": 650000,
"operation": "set"
},
{
"field_path": "operating.occupancy_rate_pct",
"new_value": 92,
"operation": "set"
}
]
}DELETE /api/co-living/analyze/{run_id}/overrides{
"override_mode": "patch",
"schema_version": "2026-05-31",
"supported_operations": [
"set",
"revert",
"remove",
"add_custom_line_item"
],
"paths": [
"property_inputs.*",
"assumptions.*",
"assumptions.financing_strategies.{strategy}.*",
"property_summary.rooms.{room_id}.*",
"financing.*",
"operating.*",
"income.per_bedroom_estimates.{room_id}.weekly_rate",
"conversion_cost.*",
"scenarios.{scenario_id}.*"
],
"fields": [
{
"path": "financing.purchase_price",
"type": "number",
"min": 0,
"operation": "set"
},
{
"path": "operating.occupancy_rate_pct",
"type": "number",
"min": 0,
"max": 100,
"operation": "set"
},
{
"path": "conversion_cost.custom_items",
"type": "object",
"operation": "add_custom_line_item"
},
{
"path": "conversion_cost.custom_items.{item_id}.estimated_cost",
"type": "number",
"min": 0,
"operation": "set"
},
{
"path": "conversion_cost.custom_items.{item_id}",
"type": "void",
"operation": "remove"
},
{
"path": "conversion_cost.per_room.{room_id}.custom_line_items.{item_id}.estimated_cost",
"type": "number",
"min": 0,
"operation": "set"
},
{
"path": "conversion_cost.per_room.{room_id}.custom_line_items.{item_id}",
"type": "void",
"operation": "remove"
},
{
"path": "scenarios.{scenario_id}.conversion_cost.per_room.{room_id}.custom_line_items.{item_id}.estimated_cost",
"type": "number",
"min": 0,
"operation": "set"
},
{
"path": "scenarios.{scenario_id}.conversion_cost.per_room.{room_id}.custom_line_items.{item_id}",
"type": "void",
"operation": "remove"
}
]
}GET /api/co-living/overrides/schema to discover editable path families and supported operations. Send updates with operation: "set", "remove", "add_custom_line_item", or "revert".Report Versions
Completed reports automatically capture an original version. Override edits and reverts create additional immutable versions.
| GET | /api/co-living/analyze/{run_id}/versions |
| GET | /api/co-living/analyze/{run_id}/versions/{version_id} |
| POST | /api/co-living/analyze/{run_id}/versions/{version_id}/revert |
{
"run_id": "atlanta-main-st-coliving",
"strategy": "co-living",
"current_version": {
"id": "a9cd5a6a-6cd3-4541-9f0f-ea823fa7d319",
"version_number": 2,
"created_at": "2026-05-14T12:10:00Z",
"history_url": "/api/co-living/analyze/atlanta-main-st-coliving/versions"
},
"versions": [
{
"id": "a9cd5a6a-6cd3-4541-9f0f-ea823fa7d319",
"version_number": 2,
"event_type": "edit",
"created_at": "2026-05-14T12:10:00Z",
"changed_fields": [
{
"path": "financing.purchase_price",
"before": 700000,
"after": 650000,
"action": "changed"
}
],
"reverted_to_version_id": null,
"is_current": true
}
]
}{
"run_id": "atlanta-main-st-coliving",
"strategy": "co-living",
"reverted_to_version": {
"id": "60ac21d0-503b-4a99-8a99-3d39919a7c80",
"version_number": 1,
"created_at": "2026-05-14T12:06:00Z",
"history_url": "/api/co-living/analyze/atlanta-main-st-coliving/versions"
},
"current_version": {
"id": "e9c70670-419e-407a-9dcc-44bdbd85cc38",
"version_number": 3,
"created_at": "2026-05-14T12:15:00Z",
"history_url": "/api/co-living/analyze/atlanta-main-st-coliving/versions"
},
"result": {}
}409. Unknown or inaccessible versions return 404.Status Codes And Billing
Report credits are reserved at start time and consumed only when the run reaches status done. Failed terminal states release the reservation.
{
"detail": "Request rate limit exceeded. Retry after 42 seconds.",
"retry_after_seconds": 42,
"limit": 600,
"window": "1 minute"
}503 instead of bypassing throttles.| Status | Meaning |
|---|---|
| 400 | Invalid JSON, invalid payload, missing query parameter, or invalid override path/value. |
| 401 | Missing, invalid, or revoked API key. |
| 402 | No report credits remaining. |
| 403 | Authenticated caller is not allowed to access the requested resource or image URL. |
| 404 | Run, deal, photo asset, or version not found, including resources owned by another user. |
| 409 | Stale optimistic-lock timestamp or invalid report-version revert. |
| 410 | Deprecated route, including co-living v2 PDF export. |
| 422 | The run state does not allow this operation, or the run predates override support. |
| 429 | Request or analysis rate limit exceeded. Check Retry-After. |
| 500 / 502 | Weston or upstream strategy backend failure. |
| 503 | Temporary database, photo service, reporting, or rate-limit service unavailability. |