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 the analysis inputs.
| POST | /api/fix-flip/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",
"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": "fix-flip",
"property_address": "123 Main St, Atlanta, GA",
"listing_url": "https://example.com/listing",
"status": "done",
"analysis_run_id": "01JZ9A2Z9V0V2K8T7D3D5E6F7G",
"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": {
"fix-flip": 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": {
"fix-flip": 26
},
"by_route": {
"analyze": 26
}
},
"events": []
}Quickstart
Start an async fix-and-flip run from a property address or listing URL, then poll the durable run id until the status is terminal.
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 analyses.
- Start a runPOST the property, listing URL, and any known input assumptions.
- Poll by run idUse the returned run_id to fetch status or completed results.
- Review the reportOpen the dashboard URL or read the structured response from your service.
- Recompute if neededUse override endpoints to intentionally replace the stored override map.
curl -X POST https://YOUR_DOMAIN/api/fix-flip/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"
},
"inputs": {
"purchase_price": 245000,
"rehab_budget": 65000
},
"metadata": {
"client_reference_id": "reno-lead-77"
}
}'Endpoints
Use these endpoints for the analysis lifecycle, report history, overrides, and PDF export.
| Method | Endpoint | Purpose |
|---|---|---|
| POST | /api/fix-flip/analyze | Start a durable async analysis run. |
| GET | /api/fix-flip/analyze/{run_id} | Fetch status or final result. Add ?status_only=true for a lightweight status envelope. |
| GET | /api/fix-flip/overrides/schema | Return accepted override paths and field metadata. |
| PATCH | /api/fix-flip/analyze/{run_id}/overrides | Replace the stored override map and recompute the completed run. |
| GET | /api/fix-flip/analyze/{run_id}/versions | List report versions. |
| GET | /api/fix-flip/analyze/{run_id}/versions/{version_id} | Fetch one version and its snapshot. |
| POST | /api/fix-flip/analyze/{run_id}/versions/{version_id}/revert | Restore a historical version and create a new current version. |
| GET | /api/fix-flip/analyze/{run_id}/report.pdf | Export the report as a PDF. |
| POST | /api/fix-flip/photo-assets/upload-intents | Create signed upload URLs for property photos. |
Request And Response
A start call returns immediately with a durable run id. Completed polls include the full report envelope.
{
"property": {
"address": "123 Main St, Atlanta, GA",
"listing_url": "https://example.com/listing"
},
"inputs": {
"purchase_price": 245000,
"rehab_budget": 65000
},
"metadata": {
"client_reference_id": "reno-lead-77"
}
}{
"run_id": "01JZ9A2Z9V0V2K8T7D3D5E6F7G",
"strategy": "fix-flip",
"status": "queued",
"created_at": "2026-05-26T12:00:00Z",
"poll_url": "/api/fix-flip/analyze/01JZ9A2Z9V0V2K8T7D3D5E6F7G",
"dashboard_url": "/reports/fix-flip/01JZ9A2Z9V0V2K8T7D3D5E6F7G"
}{
"run_id": "01JZ9A2Z9V0V2K8T7D3D5E6F7G",
"strategy": "fix-flip",
"status": "done",
"property": {
"address": "123 Main St, Atlanta, GA",
"listing_url": "https://example.com/listing"
},
"data": {
"valuation": {},
"rehab": {},
"deal_analysis": {}
},
"overrides": {},
"report_version": {
"id": "fb9d7e8c-8ec1-4b98-bf62-13f089df8a21",
"version_number": 1,
"created_at": "2026-05-26T12:08:00Z",
"history_url": "/api/fix-flip/analyze/01JZ9A2Z9V0V2K8T7D3D5E6F7G/versions"
},
"error": {
"message": null,
"code": null
}
}Overrides
Override updates replace the full stored override map. Fetch the current result first, merge intentionally in your own code, then send the entire desired map.
{
"overrides": {
"purchase_price": 235000,
"rehab_total": 70000
},
"confirm_replace": true
}GET /api/fix-flip/overrides/schemaconfirm_replace to true so accidental partial replacement fails loudly.Report Versions
Completed reports automatically capture an original version. Override edits and reverts create additional immutable versions.
| GET | /api/fix-flip/analyze/{run_id}/versions |
| GET | /api/fix-flip/analyze/{run_id}/versions/{version_id} |
| POST | /api/fix-flip/analyze/{run_id}/versions/{version_id}/revert |
{
"run_id": "01JZ9A2Z9V0V2K8T7D3D5E6F7G",
"strategy": "fix-flip",
"current_version": {
"id": "a9cd5a6a-6cd3-4541-9f0f-ea823fa7d319",
"version_number": 2,
"created_at": "2026-05-14T12:10:00Z",
"history_url": "/api/fix-flip/analyze/01JZ9A2Z9V0V2K8T7D3D5E6F7G/versions"
},
"versions": [
{
"id": "a9cd5a6a-6cd3-4541-9f0f-ea823fa7d319",
"version_number": 2,
"event_type": "edit",
"created_at": "2026-05-14T12:10:00Z",
"changed_fields": [
{
"path": "purchase_price",
"before": 245000,
"after": 235000,
"action": "changed"
}
],
"reverted_to_version_id": null,
"is_current": true
}
]
}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"
}| 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. |
| 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. |