{"openapi":"3.1.0","info":{"title":"GemstoneAI API","description":"\nGemstoneAI API - A comprehensive gemstone collection and market analysis platform.\n\n## Features\n\n* **Mobile + OTP Authentication** - Secure authentication using mobile number and OTP verification\n* **Gemstone Management** - Complete CRUD operations for gemstone collections\n* **AI Scanning** - Gemstone identification and analysis (subscription required)\n* **Subscription Management** - Tiered plans with scan limits and features\n* **Market Data** - Real-time pricing trends and market insights\n* **Profile Management** - User profiles and collection statistics\n* **Insights** - Educational articles and market analysis\n\n## Authentication Flow\n\n1. **Send OTP**: Use `/api/v1/auth/send-otp` with mobile number\n2. **Register/Login**: Use `/api/v1/auth/register` or `/api/v1/auth/login` with OTP\n3. **Access APIs**: Include Bearer token in Authorization header\n\n### New User Registration:\n1. POST `/api/v1/auth/send-otp` with `purpose: \"registration\"`\n2. POST `/api/v1/auth/register` with mobile number, OTP, and user details\n\n### Existing User Login:\n1. POST `/api/v1/auth/send-otp` with `purpose: \"login\"`\n2. POST `/api/v1/auth/login` with mobile number and OTP\n\n## Subscription Model\n\n* **AI Scanning requires active subscription** with scan limits\n* **Plans**: Basic (20 scans/month), Premium (100 scans/month), etc.\n* **Usage Tracking**: Scans used and remaining displayed in subscription status\n* **Limits Enforced**: API returns 402 Payment Required when limit exceeded\n\n## Security Features\n\n* **OTP Verification** - 6-digit OTP with 5-minute expiry\n* **Rate Limiting** - Maximum 5 OTP requests per hour per mobile number\n* **JWT Tokens** - Secure token-based authentication\n* **Mobile Validation** - International mobile number format support\n\n## File Uploads\n\nThe API supports file uploads for gemstone images and AI scanning. Files are stored in AWS S3 or locally for development.\n\nBuilt with FastAPI, SQLAlchemy, and modern security practices.\n","version":"1.0.0"},"paths":{"/api/v1/auth/send-otp":{"post":{"tags":["Authentication"],"summary":"Send Otp","description":"Send OTP for login or registration","operationId":"send_otp_api_v1_auth_send_otp_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendOTPRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OTPResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/verify-otp":{"post":{"tags":["Authentication"],"summary":"Verify Otp","description":"Verify OTP and login/register user. Links device if X-Device-Id provided.","operationId":"verify_otp_api_v1_auth_verify_otp_post","parameters":[{"name":"X-Device-Id","in":"header","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"X-Device-Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyOTPRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Token"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/user":{"get":{"tags":["Authentication"],"summary":"Get Current User Info","description":"GET /api/v1/auth/user - Get current user info","operationId":"get_current_user_info_api_v1_auth_user_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/auth/logout":{"post":{"tags":["Authentication"],"summary":"Logout","description":"POST /api/v1/auth/logout - Logout (client-side token removal)","operationId":"logout_api_v1_auth_logout_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/auth/resend-otp":{"post":{"tags":["Authentication"],"summary":"Resend Otp","description":"Resend OTP","operationId":"resend_otp_api_v1_auth_resend_otp_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendOTPRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OTPResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/send-email-otp":{"post":{"tags":["Authentication"],"summary":"Send Email Otp","description":"Send OTP to email address for login or registration","operationId":"send_email_otp_api_v1_auth_send_email_otp_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendEmailOTPRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailOTPResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/verify-email-otp":{"post":{"tags":["Authentication"],"summary":"Verify Email Otp","description":"Verify email OTP and login/register user","operationId":"verify_email_otp_api_v1_auth_verify_email_otp_post","parameters":[{"name":"X-Device-Id","in":"header","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"X-Device-Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyEmailOTPRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Token"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/resend-email-otp":{"post":{"tags":["Authentication"],"summary":"Resend Email Otp","description":"Resend OTP to email","operationId":"resend_email_otp_api_v1_auth_resend_email_otp_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendEmailOTPRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailOTPResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/refresh":{"post":{"tags":["Authentication"],"summary":"Refresh Token","description":"POST /api/v1/auth/refresh - Refresh access token using refresh token.\n\nAccepts the token either as:\n  - JSON body: {\"refreshToken\": \"...\"}\n  - Query parameter: ?refresh_token=...","operationId":"refresh_token_api_v1_auth_refresh_post","parameters":[{"name":"refresh_token","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Refresh Token"}}],"requestBody":{"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/RefreshTokenRequest"},{"type":"null"}],"title":"Request Body"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Token"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/email/register":{"post":{"tags":["Authentication"],"summary":"Email Register","description":"Register a new user with email and password. Links device if X-Device-Id provided.","operationId":"email_register_api_v1_auth_email_register_post","parameters":[{"name":"X-Device-Id","in":"header","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"X-Device-Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailRegisterRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Token"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/email/login":{"post":{"tags":["Authentication"],"summary":"Email Login","description":"Login with email and password. Links device if X-Device-Id provided.","operationId":"email_login_api_v1_auth_email_login_post","parameters":[{"name":"X-Device-Id","in":"header","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"X-Device-Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailLoginRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Token"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/google":{"post":{"tags":["Authentication"],"summary":"Google Auth","description":"Authenticate with Google ID token. Creates account on first use.\n\nLinks device if X-Device-Id provided.","operationId":"google_auth_api_v1_auth_google_post","parameters":[{"name":"X-Device-Id","in":"header","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"X-Device-Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GoogleAuthRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Token"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/apple":{"post":{"tags":["Authentication"],"summary":"Apple Auth","description":"Authenticate with an Apple identity token. Creates an account on first use.\n\nThe token is verified against Apple's JWKS (signature, iss, aud=bundle id,\nexp). Find-or-create by the stable Apple `sub`, falling back to a verified\nemail match (Apple verifies emails it returns). Issues the SAME JWT session\nshape as the email-OTP login.","operationId":"apple_auth_api_v1_auth_apple_post","parameters":[{"name":"X-Device-Id","in":"header","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"X-Device-Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppleAuthRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Token"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/device":{"post":{"tags":["Device Management"],"summary":"Create Device","description":"POST /api/v1/device\n\nRegister a new device for anonymous user tracking.\nIdempotent - calling with same device_id returns existing device.\n\nReturns device_instance_id that frontend should store permanently.","operationId":"create_device_api_v1_device_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeviceRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeviceResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/device/scan/check-limit":{"get":{"tags":["Device Management"],"summary":"Check Scan Limit","description":"GET /api/v1/device/scan/check-limit\n\nUniversal scan limit checker for all user types.\n\nHeaders:\n- Authorization: Bearer token (for authenticated users)\n- X-Device-Id: device_instance_id (for anonymous/logged-out users)\n\nReturns detailed limit information with action_required for UI.\n\nScenarios handled:\n- Anonymous user (device not linked)\n- Authenticated user (FREE or PREMIUM)\n- Logged-out user with FREE plan exhausted\n- Logged-out user with PREMIUM plan","operationId":"check_scan_limit_api_v1_device_scan_check_limit_get","parameters":[{"name":"X-Device-Id","in":"header","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"X-Device-Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScanLimitCheckResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/device/push-token":{"post":{"tags":["Device Management"],"summary":"Register Push Token","description":"POST /api/v1/device/push-token\n\nRegister or update Expo push token for notifications.\nSupports both authenticated users and anonymous devices.\n\nIdempotent: an unchanged token skips the write entirely. Clients re-POST\nthe same token on every app open, and a misbehaving one can hammer this\nroute (69,732 POSTs from a single 2.0.40 device on 2026-07-22; 25,451 from\na 2.0.41 device on 2026-08-03 — 99.2% of ALL app errors that month).\nRepeated UPDATEs of one row serialize on its lock, so the pileup turns a\n5ms write into client-side timeouts — which then defeat the client's own\npost-once-on-success guard and keep it retrying. Not writing is the brake;\nthe per-device rate limit (LNK-AUDITAPI) is the circuit breaker: a normal\nclient POSTs once per app open, a looping one gets 429s that its backoff\n(2.0.45+) treats as a hard stop for the session.","operationId":"register_push_token_api_v1_device_push_token_post","parameters":[{"name":"X-Device-Id","in":"header","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"X-Device-Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PushTokenRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/device/notification-prefs":{"post":{"tags":["Device Management"],"summary":"Update Notification Prefs","description":"POST /api/v1/device/notification-prefs\n\nUpdate the authenticated user's notification preferences. Only `push` is\nenforced server-side (gates NotificationService.send_push); email/sms are\naccepted for forward-compatibility but not yet wired to a send path.","operationId":"update_notification_prefs_api_v1_device_notification_prefs_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotificationPrefsRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/app/version-gate":{"get":{"tags":["App Meta"],"summary":"Version Gate","description":"Minimum supported app versions per platform.\n\nClient contract (2.0.45+): compare the running marketing version against\nthe platform's min using semver-ish numeric compare; below min → show a\nblocking upgrade card with the store link; equal/above → no UI. `message`\nis the card body so copy can change without a client release.","operationId":"version_gate_api_v1_app_version_gate_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionGateResponse"}}}}}}},"/api/v1/gems/portfolio/events":{"get":{"tags":["Gemstones"],"summary":"Portfolio Events","description":"GET /api/v1/gems/portfolio/events?days=365\nSaved-gem addition markers for the portfolio chart: one event per gem\nsaved in the window ({date, type:\"added\", label, value, gemstone_id},\nascending). value = the scan-time anchor, null when no estimate existed.\nStandalone while PR #53 is unmerged — can fold into\nGET /gems/portfolio/history post-#53.","operationId":"portfolio_events_api_v1_gems_portfolio_events_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":365,"minimum":1,"default":365,"title":"Days"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PortfolioEventsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gems/collection/analytics":{"get":{"tags":["Gemstones"],"summary":"Collection Analytics","description":"GET /api/v1/gems/collection/analytics\nCollection analytics: appreciation (Σ anchors vs Σ anchor × drift), top-5\n7d gainers/losers (confidence-gated), value allocation by species, and\ncollection-vs-market 7d comparison. Empty collection → all nulls/empty\nlists, 200. Reads of PR #53's tables (portfolio_snapshots,\nwatchlist_items) are guarded and degrade to per-gem math / nulls.","operationId":"collection_analytics_api_v1_gems_collection_analytics_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectionAnalyticsResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/gems/{gem_id}/value-history":{"get":{"tags":["Gemstones"],"summary":"Gem Value History","description":"GET /api/v1/gems/{gem_id}/value-history?days=90\nThe gem's own value line: anchor (estimated_value.best at scan) moved by\nits variety's daily index ratio for each day in the window with index\ndata. Unindexed variety → single flat anchor point. Owner-only — 404 for\ngems that aren't the caller's (existence not leaked).","operationId":"gem_value_history_api_v1_gems__gem_id__value_history_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"gem_id","in":"path","required":true,"schema":{"type":"integer","title":"Gem Id"}},{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":365,"minimum":7,"default":90,"title":"Days"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GemValueHistoryResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gems/list":{"get":{"tags":["Gemstones"],"summary":"List Gems","operationId":"list_gems_api_v1_gems_list_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","default":10,"title":"Page Size"}},{"name":"type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Type"}},{"name":"sort_by","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sort By"}},{"name":"X-API-Version","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Version"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GemListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gems/recent-scans":{"get":{"tags":["Gemstones"],"summary":"List User Recent Scans","description":"GET /api/v1/gems/recent-scans\nGet ALL recent scans by the authenticated user (both saved and unsaved).\n\nThis endpoint returns all gemstones scanned by the user, regardless of\nwhether they have been saved to the collection or not.","operationId":"list_user_recent_scans_api_v1_gems_recent_scans_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","default":10,"title":"Page Size"}},{"name":"X-API-Version","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Version"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GemListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gems/global-scans":{"get":{"tags":["Gemstones"],"summary":"List Global Scans","description":"GET /api/v1/gems/global-scans\nGet recent scans globally (from all users). Public endpoint - no auth required.\n\nThis endpoint returns gemstones scanned across the platform,\nuseful for a global feed or discovery feature.\n\nAbuse hardening:\n- page_size is clamped to 1..50 (the app requests 5); page is clamped >= 1\n- rate limited per client IP (RATE_LIMIT_GLOBAL_SCANS, default 30/minute)\n- user identifiers are stripped from every item (user_id forced to null)","operationId":"list_global_scans_api_v1_gems_global_scans_get","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","default":10,"title":"Page Size"}},{"name":"X-API-Version","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Version"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GemListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gems/scan-progress/{token}":{"get":{"tags":["Gemstones"],"summary":"Get Scan Progress","description":"Findings a running scan has reached, polled by the app's wait screen.\n\nThe token is a random id the app generated and sent with the photos; it is\nthe only key, and the events carry nothing the scan result does not.","operationId":"get_scan_progress_api_v1_gems_scan_progress__token__get","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gems/{gem_id}/details":{"get":{"tags":["Gemstones"],"summary":"Get Gemstone","description":"GET /api/v1/gems/{id} - Get gemstone details.\n\nDual-owner (LNK-DETAILSANON): resolve by user_id when authenticated OR by\ndevice_id, mirroring POST /gems/scan. A scan created device-scoped (the\napp running without a usable token) is otherwise unreadable by its own\npoll — which is why the comparables async-fill never surfaced for\nlogged-out/anonymous sessions. The device side reaches only recent\nunclaimed guest scans (LNK-DEVAUTH, services/guest_claim.py).","operationId":"get_gemstone_api_v1_gems__gem_id__details_get","parameters":[{"name":"gem_id","in":"path","required":true,"schema":{"type":"string","title":"Gem Id"}},{"name":"X-Device-Id","in":"header","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"X-Device-Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Version","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Version"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GemstoneResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gems/{gem_id}":{"delete":{"tags":["Gemstones"],"summary":"Delete Gemstone","description":"DELETE /api/v1/gems/{id} - Delete gemstone\n\nDeletes a gemstone and all its associated images.\nOnly the owner of the gemstone can delete it.\n\nArgs:\n    gem_id: ID of the gemstone to delete\n\nReturns:\n    GemstoneDeleteResponse: Success status and deletion details\n\nRaises:\n    HTTPException 400: Invalid gemstone ID format\n    HTTPException 404: Gemstone not found or unauthorized\n    HTTPException 500: Database error","operationId":"delete_gemstone_api_v1_gems__gem_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"gem_id","in":"path","required":true,"schema":{"type":"string","title":"Gem Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GemstoneDeleteResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["Gemstones"],"summary":"Gem Detail","description":"Get detailed info of a gemstone by its ID.\nRequires authentication.","operationId":"gem_detail_api_v1_gems__gem_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"gem_id","in":"path","required":true,"schema":{"type":"integer","title":"Gem Id"}},{"name":"X-API-Version","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Version"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GemstoneResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["Gemstones"],"summary":"Update Gemstone","description":"PUT /api/v1/gems/{id} — partial update of user-editable fields (LNK-GEMRENAME).\n\nThe save prompt's rename (app LNK-AUDITAPP) calls this feature-detected with\n{\"name\": str}; name is the piece title, stored on main_heading. Only fields\nthe client sends change. Dual-owner resolution mirrors GET /{gem_id}/details\n(LNK-DETAILSANON): user_id when authenticated OR device_id via X-Device-Id,\nwith the owner filter inside the query so a foreign gem 404s without\nleaking existence.","operationId":"update_gemstone_api_v1_gems__gem_id__put","parameters":[{"name":"gem_id","in":"path","required":true,"schema":{"type":"integer","title":"Gem Id"}},{"name":"X-Device-Id","in":"header","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"X-Device-Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Version","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Version"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GemstoneUpdateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GemstoneResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gems/upload":{"post":{"tags":["Gemstones"],"summary":"Upload Gem Image","description":"POST /api/v1/gems/upload — attach an additional image to an existing gemstone.","operationId":"upload_gem_image_api_v1_gems_upload_post","requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_upload_gem_image_api_v1_gems_upload_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/gems/scan":{"post":{"tags":["Gemstones"],"summary":"Scan Gemstone Endpoint","description":"POST /api/v1/gems/scan — single-call GPT-5.5 Pro scan (LNK-G55R + LNK-SIA).\n\nTwo modes (controlled by scan_intent + item_id):\n\n  new_item (default): creates a new Gemstone row with the uploaded images.\n                      Existing behavior — backwards compatible.\n\n  add_angle:          attaches new images to an existing Gemstone (item_id),\n                      re-runs scan_v2 with the FULL image set (≤5 cap),\n                      updates the canonical Gemstone fields in place, and\n                      creates a Scan history row. First add_angle per Item\n                      is free (no quota consumed). Subsequent add_angles\n                      on the same Item count normally.\n\nPipeline (new_item):\n  1. Validate auth + images; a fingerprint cache hit on the caller's OWN\n     earlier scan returns the stored result here, uncharged and exempt\n     from the limit (LNK-SCANIDEM)\n  2. Scan limits + quota reservation (cache miss only); persist images\n  3. scan_v2(images, edge_hint) — Gemini pre-pass + GPT-5.5 Pro w/ web_search\n  4. ScanV2Result Pydantic validation (surfaces malformed AI output as 5xx)\n  5. Persist via ScanService.process_scan_v2_result (scan_version = 2)\n  6. Increment scan / device counter\n  7. Return ScanV2SuccessResponse{gemstone_id, images, scan}\n\nPipeline (add_angle):\n  1. Validate auth + scan limits (free if first add_angle for this Item)\n  2. Load existing Gemstone, validate ownership + combined image count ≤ 5\n  3. Validate + persist new images\n  4. Fetch existing images, combine with new, run scan_v2 with full set\n  5. ScanV2Result validation\n  6. Persist via ScanService.process_add_angle_result (update in place,\n     add new GemstoneImage rows linked to the new Scan, increment\n     add_angle_count)\n  7. Increment scan counter only if NOT free\n  8. Return ScanV2SuccessResponse{gemstone_id=item_id, images, scan}\n\nForm fields (LNK-SIA additions):\n  item_id     (Optional[int])  — existing gemstone.id; required if scan_intent=add_angle\n  scan_intent (Optional[str])  — 'new_item' (default) or 'add_angle'\n\nHeaders:\n  Authorization (optional)  — Bearer JWT for authenticated users\n  X-Device-Id               — device instance id; REQUIRED for anonymous\n                              scans (register via POST /api/v1/device first)\n  X-Scan-Source             — \"mobile\" (default) or \"web\" (requires auth)\n\nLimits (LNK-LADDER):\n  Authenticated FREE    — base 1 scan/month + earned bonus scans\n                          (signup +1, first save-to-collection +1);\n                          1 free add_angle per Item\n  Authenticated PREMIUM — unlimited\n  Anonymous             — 1 free scan (ANONYMOUS_SCAN_LIMIT), tracked per\n                          device. Requests without X-Device-Id are rejected\n                          with 400 — there is no untracked anonymous mode.\n\nReturns:\n  200 ScanV2SuccessResponse — successful scan, full v2 result included\n  200 ScanV2ErrorResponse   — image rejected (not a gemstone) or AI failure\n  400                       — invalid scan_intent / image cap exceeded /\n                              anonymous scan without X-Device-Id header\n  401                       — web scan without authentication\n  402                       — scan limit exceeded\n  403                       — add_angle on Item owned by someone else\n  404                       — add_angle item_id not found","operationId":"scan_gemstone_endpoint_api_v1_gems_scan_post","parameters":[{"name":"X-Device-Id","in":"header","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"X-Device-Id"}},{"name":"X-Scan-Source","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Scan-Source"}},{"name":"X-App-Version","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-App-Version"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Version","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Version"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_scan_gemstone_endpoint_api_v1_gems_scan_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/ScanV2SuccessResponse"},{"$ref":"#/components/schemas/ScanV2ErrorResponse"}],"title":"Response Scan Gemstone Endpoint Api V1 Gems Scan Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gems/save/collection":{"post":{"tags":["Gemstones"],"summary":"Save Scan To Collection","description":"POST /api/v1/gems/save/collection\nSave multiple scanned gemstones to user's permanent collection.\n\nSupports saving multiple gemstones at once from a multi-gemstone scan.\nLimited by free saves (50 for free users, unlimited for subscribers).\n\nLNK-LADDER: the user's FIRST successful save grants +1 bonus scan. The\nresponse items additively carry {\"bonus_granted\": true, \"scans_remaining\": n}\non the grant-ing save so the app can toast it (old clients ignore the\nunknown fields; the array shape is unchanged).\n\nArgs:\n    gemstone_ids: List of gemstone IDs to save\n\nReturns:\n    List of saved SavedGemstoneResponse objects\n\nRaises:\n    HTTPException 400: Invalid or missing gemstone IDs\n    HTTPException 402: Save limit reached\n    HTTPException 404: Some gemstones not found\n    HTTPException 500: Database error","operationId":"save_scan_to_collection_api_v1_gems_save_collection_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"X-API-Version","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Version"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Body_save_scan_to_collection_api_v1_gems_save_collection_post"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SavedGemstoneResponse"},"title":"Response Save Scan To Collection Api V1 Gems Save Collection Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gems/analytics":{"get":{"tags":["Gemstones"],"summary":"Gems Analytics","description":"GET /api/v1/gems/analytics\nGet analytics summary for user's gemstone collection.","operationId":"gems_analytics_api_v1_gems_analytics_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GemAnalyticsResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/gems/collection/by-species":{"get":{"tags":["Gemstones"],"summary":"Collection By Species","description":"GET /api/v1/gems/collection/by-species\nPer-species rollup (count + combined estimated value) of the caller's saved\ncollection. Powers the mobile \"In Your Collection\" cross-link on the scan\nresult page. Scoped to the authenticated user, or the X-Device-Id device for\nanonymous callers. Additive + read-only.\n\nAuth is optional-strict (LNK-ZEROLIE): callers with no Authorization header\nare anonymous and fall back to X-Device-Id, but a caller who presents a\ntoken that no longer works gets a 401 rather than the anonymous empty list.\nReturning [] to an expired session made the app paint an empty collection\nover a real one.\n\nThe \"Unidentified\" placeholder a stone-free piece carries is not a species,\nso it gets no row: \"You own 7 Unidentifieds\" read as a failure on a shelf of\ngold bands. [LNK-NOSTONEROW]","operationId":"collection_by_species_api_v1_gems_collection_by_species_get","parameters":[{"name":"X-Device-Id","in":"header","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"X-Device-Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CollectionSpeciesSummary"},"title":"Response Collection By Species Api V1 Gems Collection By Species Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gems/portfolio":{"get":{"tags":["Gemstones"],"summary":"Gems Portfolio","description":"GET /api/v1/gems/portfolio\nPortfolio summary aggregated from the persisted estimated_value JSON\n({currency, best, range_min, range_max} — written by ScanService) on the\nuser's saved gems. Null-safe: gems without a usable value count toward\ntotal_gems but are skipped in the sums.\n\nFixed 2026-06-09: previously imported app.services.valuation_service,\nwhich was never committed — the endpoint 500'd on every call since it\nshipped (2026-04-02). Valuation lives in the persisted estimated_value\nJSON since the 2026-05-21 scan rewrite.","operationId":"gems_portfolio_api_v1_gems_portfolio_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PortfolioSummaryResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/gems/portfolio/history":{"get":{"tags":["Gemstones"],"summary":"Portfolio History","description":"GET /api/v1/gems/portfolio/history?days=30\nDaily portfolio value series (LNK-DRIFT) written by the 07:30 UTC snapshot\njob: each gem's scan-time anchor moved by its variety's index drift.\nSelf-contained — does not depend on GET /gems/portfolio. Null-safe while\nsnapshot history is still accruing (<2 points).","operationId":"portfolio_history_api_v1_gems_portfolio_history_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":3650,"minimum":1,"default":30,"title":"Days"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PortfolioHistoryResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gems/{gem_id}/chat":{"post":{"tags":["Gemstones"],"summary":"Send Chat Message","description":"POST /api/v1/gems/{gem_id}/chat - Send a chat message to refine gemstone scan data\n\nAllows users to provide additional context or corrections to their gemstone scan.\nThe AI validates the message against the original images and either updates the\ngemstone data or rejects contradictory requests.\n\nArgs:\n    gem_id: ID of the gemstone to chat about\n    request: ChatMessageRequest with user's message\n    current_user: Authenticated user\n    db: Database session\n\nReturns:\n    ChatMessageResponse with message details (same format as history)","operationId":"send_chat_message_api_v1_gems__gem_id__chat_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"gem_id","in":"path","required":true,"schema":{"type":"integer","title":"Gem Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatMessageRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatMessageResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gems/{gem_id}/chat/history":{"get":{"tags":["Gemstones"],"summary":"Get Chat History","description":"GET /api/v1/gems/{gem_id}/chat/history - Get conversation history for a gemstone\n\nRetrieves all chat messages associated with a gemstone scan, including both\naccepted refinements and rejected requests.\n\nArgs:\n    gem_id: ID of the gemstone\n    current_user: Authenticated user\n    db: Database session\n\nReturns:\n    ChatHistoryResponse with list of all messages","operationId":"get_chat_history_api_v1_gems__gem_id__chat_history_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"gem_id","in":"path","required":true,"schema":{"type":"integer","title":"Gem Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatHistoryResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gems/{gem_id}/investment":{"patch":{"tags":["Gemstones"],"summary":"Update Gem Investment","description":"PATCH /api/v1/gems/{gem_id}/investment (LNK-MKT2)\nSet or clear the gem's purchase price / date. Owner-only — same user/device\nownership rules as other gem mutations (authenticated users own by user_id,\nanonymous devices by X-Device-Id). Null purchase_price_usd clears the\ninvestment data. Returns the updated \"investment\" block (null when cleared).","operationId":"update_gem_investment_api_v1_gems__gem_id__investment_patch","parameters":[{"name":"gem_id","in":"path","required":true,"schema":{"type":"integer","title":"Gem Id"}},{"name":"X-Device-Id","in":"header","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"X-Device-Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvestmentUpdateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/GemInvestmentBlock"},{"type":"null"}],"title":"Response Update Gem Investment Api V1 Gems  Gem Id  Investment Patch"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gems/{gem_id}/records":{"patch":{"tags":["Gemstones"],"summary":"Update Gem Records","description":"PATCH /api/v1/gems/{gem_id}/records (LNK-RECORDS)\n\nRecord the owner's own facts about their piece: measurements, carat weight,\nlab report, notes. True partial patch — an omitted field is left untouched,\nan explicit null clears just that field. Returns the updated block, or null\nonce the last recorded field is cleared.\n\nOwner-only. Dual-owner resolution follows GET /{gem_id}/details and PUT\n/{gem_id} (LNK-DETAILSANON / LNK-GEMRENAME): user_id when authenticated OR\ndevice_id via X-Device-Id, with the owner filter inside the query so a\nforeign gem 404s without leaking that it exists. Note the sibling\nPATCH /{gem_id}/investment still fetches first and 403s — it leaks\nexistence; this route deliberately does not copy that.\n\nThese values remain owner claims. Weight, quantity and scope changes\nrecalculate valuation; when evidence pricing is enabled, measurement edits\nalso trigger a separate evidence valuation. Scan estimates stay separate.","operationId":"update_gem_records_api_v1_gems__gem_id__records_patch","parameters":[{"name":"gem_id","in":"path","required":true,"schema":{"type":"integer","title":"Gem Id"}},{"name":"X-Device-Id","in":"header","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"X-Device-Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordsUpdateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/GemRecordsBlock"},{"type":"null"}],"title":"Response Update Gem Records Api V1 Gems  Gem Id  Records Patch"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gems/{gem_id}/identification":{"patch":{"tags":["Gemstones"],"summary":"Update Gem Identification","description":"PATCH /api/v1/gems/{gem_id}/identification (LNK-IDFIX)\n\nThe owner overrules the scan's species, and the valuation follows.\n\nTwo things happen, in this order and for a reason. First the correction is\nwritten: species, title, and the preserved record of what we said. Then the\ngem is re-priced against the corrected species. If the re-pricing fails or\nfinds no market data, the CORRECTION STILL STANDS and the gem comes back\nwith no estimate — never with the price that belonged to the rejected\nidentification. A moissanite price under the heading \"Blue Zircon\" reads as\nthough we priced the corrected stone, and that is the exact failure this\nendpoint exists to undo.\n\nRe-pricing re-runs the valuation only: comps, macro index, metal melt,\nsanity cap. No vision, no LLM, no image re-read, and so no scan quota is\ncharged. A correction must never cost the owner a scan for telling us we\nwere wrong.\n\nSpecies outside our taxonomy are accepted, flagged `off_catalog`, and\ngenerally come back `revalued: false` — we hold no market series for them.\nRefusing them would mean refusing exactly the corrections most worth having.\n\nOwner-only, resolved the same way as PATCH /{gem_id}/records: user_id when\nauthenticated OR device_id via X-Device-Id, with the owner filter inside the\nquery so a foreign gem 404s without leaking that it exists.","operationId":"update_gem_identification_api_v1_gems__gem_id__identification_patch","parameters":[{"name":"gem_id","in":"path","required":true,"schema":{"type":"integer","title":"Gem Id"}},{"name":"X-Device-Id","in":"header","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"X-Device-Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IdentificationUpdateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IdentificationUpdateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gems/{gem_id}/deep-scan/status":{"get":{"tags":["Gemstones"],"summary":"Deep Scan Status Stub","description":"Backwards compat stub — v2 pipeline returns results synchronously, no polling needed.","operationId":"deep_scan_status_stub_api_v1_gems__gem_id__deep_scan_status_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"gem_id","in":"path","required":true,"schema":{"type":"integer","title":"Gem Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gems/{gem_id}/combine":{"post":{"tags":["Gemstones"],"summary":"Combine Same Piece","description":"[LNK-RESCAN] The user says scan `gem_id` is the same piece as the\nearlier scan `into_id`. Folds it in: one item, one estimate combining both\nreads, photos and scan history kept. `gem_id` is removed.","operationId":"combine_same_piece_api_v1_gems__gem_id__combine_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"gem_id","in":"path","required":true,"schema":{"type":"integer","title":"Gem Id"}},{"name":"X-API-Version","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Version"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CombineSamePieceRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CombineSamePieceResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gems/feedback":{"post":{"tags":["Gemstones"],"summary":"Submit Scan Feedback","description":"POST /api/v1/gems/feedback\nSubmit user feedback on scan accuracy.\nOwner only: the signed-in owner, or the device that took a recent\nunclaimed guest scan (LNK-THUMBS; same rule as LNK-DEVAUTH reads).\n\nRequest body:\n- gemstone_id: ID of the gemstone\n- is_accurate: True if scan is accurate, False if not\n\nReturns:\n- success: True if feedback was saved successfully\n- message: Response message\n- gemstone_id: ID of the gemstone","operationId":"submit_scan_feedback_api_v1_gems_feedback_post","parameters":[{"name":"X-Device-Id","in":"header","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"X-Device-Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScanFeedbackRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScanFeedbackResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gems/{gem_id}/price-feedback":{"post":{"tags":["Gemstones"],"summary":"Submit Price Feedback","description":"POST /api/v1/gems/{gem_id}/price-feedback — consumer 👍👎 on a scan's valuation.\n\nCaptures whether the user thinks the estimated price is too low / about right\n/ too high, plus an optional own-price guess. Persisted to scan_price_feedback\nas a labeled example (with the scan's price context) for future pricing eval\nand the consumer 👍👎 UI (app pair feat/2026-06-09-price-feedback-ui, LNK-PFB).\n\nAuth required; users can only give feedback on their own gems. Idempotent per\ngem: the latest verdict for a gem wins (re-tapping updates the same row rather\nthan appending), so the table stays one consumer-label row per gemstone.\n\nBody:\n- verdict: \"too_low\" | \"about_right\" | \"too_high\"\n- user_estimate: optional number (the user's own price guess, USD)\n\nReturns the saved scan_price_feedback row.","operationId":"submit_price_feedback_api_v1_gems__gem_id__price_feedback_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"gem_id","in":"path","required":true,"schema":{"type":"integer","title":"Gem Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PriceFeedbackRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PriceFeedbackResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gems/illustrations/studio":{"get":{"tags":["Gemstones"],"summary":"Studio Renders","description":"The caller's ready studio renders keyed by gem id; empty when dark.","operationId":"studio_renders_api_v1_gems_illustrations_studio_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StudioRendersResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gems/{gem_id}/illustration":{"get":{"tags":["Gemstones"],"summary":"Get Illustration","operationId":"get_illustration_api_v1_gems__gem_id__illustration_get","parameters":[{"name":"gem_id","in":"path","required":true,"schema":{"type":"integer","title":"Gem Id"}},{"name":"kind","in":"query","required":false,"schema":{"enum":["breakdown","studio"],"type":"string","default":"breakdown","title":"Kind"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IllustrationResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["Gemstones"],"summary":"Request Illustration","operationId":"request_illustration_api_v1_gems__gem_id__illustration_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"gem_id","in":"path","required":true,"schema":{"type":"integer","title":"Gem Id"}},{"name":"kind","in":"query","required":false,"schema":{"enum":["breakdown","studio"],"type":"string","default":"breakdown","title":"Kind"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IllustrationResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/valuations/collection":{"get":{"tags":["Valuations"],"summary":"History","operationId":"history_api_v1_valuations_collection_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":3650,"minimum":1,"default":30,"title":"Days"}},{"name":"basis","in":"query","required":false,"schema":{"enum":["purchase","resale"],"type":"string","default":"purchase","title":"Basis"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/valuations/items/{gem_id}":{"get":{"tags":["Valuations"],"summary":"Item History","operationId":"item_history_api_v1_valuations_items__gem_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"gem_id","in":"path","required":true,"schema":{"type":"integer","title":"Gem Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/valuations/items/{gem_id}/requests":{"post":{"tags":["Valuations"],"summary":"Request Input","operationId":"request_input_api_v1_valuations_items__gem_id__requests_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"gem_id","in":"path","required":true,"schema":{"type":"integer","title":"Gem Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InputRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/valuations/items/{gem_id}/refresh":{"post":{"tags":["Valuations"],"summary":"Refresh Components","operationId":"refresh_components_api_v1_valuations_items__gem_id__refresh_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"gem_id","in":"path","required":true,"schema":{"type":"integer","title":"Gem Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ComponentRefreshResult"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/valuations/collection/refresh":{"post":{"tags":["Valuations"],"summary":"Refresh Collection","operationId":"refresh_collection_api_v1_valuations_collection_refresh_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/market/watches":{"get":{"tags":["Watch Index"],"summary":"Watch Index Overview","operationId":"watch_index_overview_api_v1_market_watches_get","parameters":[{"name":"brand","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Limit collections and references to one brand","title":"Brand"},"description":"Limit collections and references to one brand"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/market/watches/{brand}/{reference}":{"get":{"tags":["Watch Index"],"summary":"Watch Reference Detail","operationId":"watch_reference_detail_api_v1_market_watches__brand___reference__get","parameters":[{"name":"brand","in":"path","required":true,"schema":{"type":"string","title":"Brand"}},{"name":"reference","in":"path","required":true,"schema":{"type":"string","title":"Reference"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/market/import":{"post":{"tags":["Market"],"summary":"Import Market Data","description":"Import gemstone market data from CSV or Excel file.\nAdmin-only (X-Admin-Key). Upserts the rows behind the Markets tab and\nscan valuations, so an unauthenticated caller could rewrite pricing.\n\nFor Excel: Merges data from multiple sheets:\n- \"Description\": Textual characteristics, value drivers, market dynamics, insights.\n- \"Price v2\": Pricing, historical avgs, event notes.\n\nExpected columns match sheet headers (see schema aliases).\nMerges on 'Variety'; partial data is handled gracefully.","operationId":"import_market_data_api_v1_market_import_post","parameters":[{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_import_market_data_api_v1_market_import_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/market/data":{"get":{"tags":["Market"],"summary":"Get Market Data","description":"Get gemstone market data for the 'Market Benchmarks' listing page.\n\nOpen to all tiers (LNK-MKTTAB): the markets list is a retention surface;\nmonetization gates live on the scan path. The old 5-row free cap only\nproduced a broken-looking table (its client-side upsell was dead code)\nwhile /market/index served all rows uncapped anyway.\n\nReturns paginated, sorted variety-wise data with:\n- variety: Gemstone name (sortable)\n- avg/min/max: curated 2025 prices in raw dollars\n- change: % change based on period (never null — 0.0 when unknowable)\n- embedded live-index fields (index_value, change_1d/7d/30d_pct,\n  confidence_tier, sparkline_7d, tier) so the table needs no second\n  endpoint; null/[] for unindexed varieties\n\nPeriod calculations (LNK-MKTCOHERE):\n- 1month: live GemstoneAI index change_30d_pct — the same number the\n  variety detail page leads with\n- 6month: interpolated from mid-2024 to 2025 (legacy; app hides this tab)\n- 1year: direct 2024-2025 YoY % from curated annual averages, clamped to\n  the same +/-15% display cap as every other served change (LNK-MKTTAB)\n\nSorting: value sorts order by the number the Index column displays\n(index_value, curated avg fallback); change sorts by the computed change\nactually displayed for the selected period.","operationId":"get_market_data_api_v1_market_data_get","parameters":[{"name":"period","in":"query","required":false,"schema":{"enum":["1month","6month","1year"],"type":"string","description":"Time period for calculating change percentage (matches UI tabs)","default":"1month","title":"Period"},"description":"Time period for calculating change percentage (matches UI tabs)"},{"name":"sort_by","in":"query","required":false,"schema":{"enum":["variety_asc","variety_desc","avg_desc","avg_asc","change_desc","change_asc"],"type":"string","description":"Sort results: variety_asc (default), variety_desc, avg_desc/avg_asc (by the displayed index value, curated avg fallback), change_desc/change_asc (by the displayed period change)","default":"variety_asc","title":"Sort By"},"description":"Sort results: variety_asc (default), variety_desc, avg_desc/avg_asc (by the displayed index value, curated avg fallback), change_desc/change_asc (by the displayed period change)"},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"Page number (starts from 1)","default":1,"title":"Page"},"description":"Page number (starts from 1)"},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Number of items per page","default":10,"title":"Page Size"},"description":"Number of items per page"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketDataListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/market/data/{gemstone_id}":{"get":{"tags":["Market"],"summary":"Get Gemstone By Id","description":"Get complete details of a specific gemstone by its ID.\n\nReturns comprehensive gemstone market data including:\n- Basic information (variety, source, characteristics)\n- Value drivers (carat, color, clarity, cut - with descriptions and star ratings)\n- Market dynamics (supply, demand, trends)\n- Market insights (up to 6 key facts)\n- 2025 pricing details (min, avg, max, percentiles, YoY change) + computed UI fields (e.g., $K formats, YoY calc)\n- Historical pricing (2020-2025 with event notes + $K for graph)\n- Metadata (created_at, updated_at timestamps)\n\nAll UI computations (e.g., $K formatting, YoY %, graph-ready data) are done backend-only to reduce client load.\nNo variety-based queries; ID-only for security/scalability.\n\nArgs:\n    gemstone_id: Unique integer ID of the gemstone record\n\nReturns:\n    GemstoneMarketDetailResponse: Complete gemstone details with pre-computed UI data\n\nRaises:\n    HTTPException 404: If gemstone with given ID is not found\n    HTTPException 500: If database error occurs","operationId":"get_gemstone_by_id_api_v1_market_data__gemstone_id__get","parameters":[{"name":"gemstone_id","in":"path","required":true,"schema":{"type":"integer","title":"Gemstone Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GemstoneMarketDetailResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/market/estimate":{"get":{"tags":["Market"],"summary":"Get Market Estimate","description":"Get a market-backed price estimate for a gemstone based on its characteristics.\n\nUses the internal pricing engine which computes estimates from price observations,\nscan feedback, and market data.","operationId":"get_market_estimate_api_v1_market_estimate_get","parameters":[{"name":"type","in":"query","required":true,"schema":{"type":"string","description":"Gemstone type (e.g. Sapphire, Ruby, Emerald)","title":"Type"},"description":"Gemstone type (e.g. Sapphire, Ruby, Emerald)"},{"name":"carat","in":"query","required":false,"schema":{"type":"number","exclusiveMinimum":0.0,"description":"Carat weight","default":1.0,"title":"Carat"},"description":"Carat weight"},{"name":"color","in":"query","required":false,"schema":{"type":"string","description":"Color family","default":"","title":"Color"},"description":"Color family"},{"name":"clarity","in":"query","required":false,"schema":{"type":"string","description":"Clarity grade","default":"","title":"Clarity"},"description":"Clarity grade"},{"name":"shape","in":"query","required":false,"schema":{"type":"string","description":"Shape/cut style","default":"","title":"Shape"},"description":"Shape/cut style"},{"name":"cut","in":"query","required":false,"schema":{"type":"string","description":"Cut grade","default":"","title":"Cut"},"description":"Cut grade"},{"name":"origin","in":"query","required":false,"schema":{"type":"string","description":"Geographic origin","default":"","title":"Origin"},"description":"Geographic origin"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketEstimateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/market/v2/overview":{"get":{"tags":["Market V2"],"summary":"Get Market Overview","description":"GET /api/v1/market/v2/overview\nPersonalized markets homepage: daily pulse (null until first generation),\nmetal prices, your_market (owned varieties by est value desc), watchlist,\n1d movers, and news with owned/watched varieties boosted to the top.\nAnonymous callers without X-Device-Id get the generic payload.","operationId":"get_market_overview_api_v1_market_v2_overview_get","parameters":[{"name":"X-Device-Id","in":"header","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"X-Device-Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketOverviewResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/market/v2/variety/{variety}":{"get":{"tags":["Market V2"],"summary":"Get Variety Page","description":"GET /api/v1/market/v2/variety/{variety}\nFull variety-page payload: index block + honest history_periods, signal\nbreakdown, pricing ladder, comps preview (8 newest with image), news\n(variety-tagged, padded with general items flagged is_family_level),\nspecies content / supply / market data (null when unpopulated), and the\ncaller's position in this variety. 404 for varieties the index doesn't track.","operationId":"get_variety_page_api_v1_market_v2_variety__variety__get","parameters":[{"name":"variety","in":"path","required":true,"schema":{"type":"string","title":"Variety"}},{"name":"X-Device-Id","in":"header","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"X-Device-Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VarietyPageResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/markets/{variety}/listings":{"get":{"tags":["Markets"],"summary":"Variety Listings","description":"GET /api/v1/markets/{variety}/listings?limit=5\nRecent price observations for an index-tracked variety, newest first.\n404 when the variety isn't in price_index_daily. Items carry\n{title, price, carat, source, observed_at} — no URLs in v1.","operationId":"variety_listings_api_v1_markets__variety__listings_get","parameters":[{"name":"variety","in":"path","required":true,"schema":{"type":"string","title":"Variety"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":20,"minimum":1,"default":5,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VarietyListingsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/markets/watchlist":{"get":{"tags":["Markets"],"summary":"Get Watchlist","description":"GET /api/v1/markets/watchlist\nThe caller's watched varieties (newest first) with each variety's latest\nindex value and 7-day change.","operationId":"get_watchlist_api_v1_markets_watchlist_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WatchlistResponse"}}}}},"security":[{"HTTPBearer":[]}]},"post":{"tags":["Markets"],"summary":"Add Watchlist Item","description":"POST /api/v1/markets/watchlist {\"variety\": str}\nAdd a price-index variety to the caller's watchlist. The variety must\nexist in price_index_daily (matched case-insensitively, stored in its\ncanonical casing) — 422 otherwise. Idempotent: re-adding an already\nwatched variety returns the existing item.","operationId":"add_watchlist_item_api_v1_markets_watchlist_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WatchlistAddRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WatchlistItemResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/markets/watchlist/{variety}":{"delete":{"tags":["Markets"],"summary":"Remove Watchlist Item","description":"DELETE /api/v1/markets/watchlist/{variety}\nRemove a variety (matched case-insensitively) from the caller's watchlist.\n404 when the variety isn't on it.","operationId":"remove_watchlist_item_api_v1_markets_watchlist__variety__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"variety","in":"path","required":true,"schema":{"type":"string","title":"Variety"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WatchlistDeleteResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/profile":{"get":{"tags":["Profile"],"summary":"Get Profile","description":"GET /api/v1/profile","operationId":"get_profile_api_v1_profile_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserResponse"}}}}},"security":[{"HTTPBearer":[]}]},"put":{"tags":["Profile"],"summary":"Update Profile","description":"PUT /api/v1/profile - Update user profile with optional avatar upload","operationId":"update_profile_api_v1_profile_put","requestBody":{"content":{"multipart/form-data":{"schema":{"allOf":[{"$ref":"#/components/schemas/Body_update_profile_api_v1_profile_put"}],"title":"Body"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/profile/attribution":{"post":{"tags":["Profile"],"summary":"Set Attribution","description":"POST /api/v1/profile/attribution — persist first-touch install attribution.\n\nWrite-once: after attribution_captured_at is set the record is immutable,\nso re-syncs from the app (or replays) can't overwrite first-touch.","operationId":"set_attribution_api_v1_profile_attribution_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AttributionPayload"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AttributionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/profile/mark-tour-complete":{"post":{"tags":["Profile"],"summary":"Mark Tour Complete","description":"POST /api/v1/profile/mark-tour-complete — flag the in-app onboarding tour\nas finished/skipped for this user (LNK-TOUR). Idempotent.","operationId":"mark_tour_complete_api_v1_profile_mark_tour_complete_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/profile/stats":{"get":{"tags":["Profile"],"summary":"Get Profile Stats","operationId":"get_profile_stats_api_v1_profile_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserProfileStats"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/profile/delete":{"delete":{"tags":["Profile"],"summary":"Delete User Account","description":"DELETE /api/v1/profile/delete\nPermanently delete user account and ALL associated data (HARD DELETE).\n\nThis endpoint performs a complete deletion of:\n- User account\n- All gemstones and their images\n- Physical image files from storage\n- Subscription rows are detached, not deleted: user_id goes NULL and only\n  store/billing facts and the numeric RevenueCat id remain (LNK-SUBKEEP)\n- All OTP records\n\n⚠️ WARNING: This action is IRREVERSIBLE. All data will be permanently deleted.\n\nReturns:\n    UserDeletionResponse with deletion statistics\n\nRaises:\n    HTTPException 404: User not found\n    HTTPException 500: Deletion failed","operationId":"delete_user_account_api_v1_profile_delete_delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"X-Apple-Authorization-Code","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Apple-Authorization-Code"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserDeletionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/referral/me":{"get":{"tags":["Referral"],"summary":"Get Referral Me","description":"The caller's referral code (lazily generated), share URL, and stats.","operationId":"get_referral_me_api_v1_referral_me_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReferralMeResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/referral/redeem":{"post":{"tags":["Referral"],"summary":"Redeem Referral Code","description":"Redeem a friend's referral code. One redemption per account, ever.\n\nErrors: 400 empty/self code, 404 unknown code, 409 already redeemed,\n429 when rate limited.","operationId":"redeem_referral_code_api_v1_referral_redeem_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReferralRedeemRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReferralRedeemResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/promo/redeem":{"post":{"tags":["Promo Codes"],"summary":"Redeem Promo Code","description":"Redeem a promo code. One promo redemption per account, ever.\n\nErrors: 400 empty code, 403 reserved for another email, 404 unknown code,\n409 already redeemed / code expired or exhausted, 429 rate limited.","operationId":"redeem_promo_code_api_v1_promo_redeem_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PromoRedeemRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PromoRedeemResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/promo/{code}":{"get":{"tags":["Promo Codes"],"summary":"Preview Promo Code","description":"Check a code before signing up. Rate limited — this is a guessable surface.","operationId":"preview_promo_code_api_v1_promo__code__get","parameters":[{"name":"code","in":"path","required":true,"schema":{"type":"string","title":"Code"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PromoPreviewResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/coverage/intent":{"post":{"tags":["Coverage"],"summary":"Record Coverage Intent","description":"Record that a user wants a catalogued piece covered or appraised.\n\nIdempotent per (user, piece, kind): tapping twice refreshes the row rather\nthan counting twice.","operationId":"record_coverage_intent_api_v1_coverage_intent_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CoverageIntentRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CoverageIntentResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/coverage/intents":{"get":{"tags":["Coverage"],"summary":"List Coverage Intents","description":"What this user has already flagged, so the UI can show it as done.","operationId":"list_coverage_intents_api_v1_coverage_intents_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CoverageIntentListResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/coverage/providers":{"get":{"tags":["Coverage"],"summary":"List Coverage Providers","description":"Where to actually go. Server-driven so the list can change without a\nstore release, which matters because there is no OTA channel.","operationId":"list_coverage_providers_api_v1_coverage_providers_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"kind","in":"query","required":true,"schema":{"type":"string","description":"coverage | appraisal","title":"Kind"},"description":"coverage | appraisal"},{"name":"item_value","in":"query","required":false,"schema":{"anyOf":[{"type":"number","minimum":0.0},{"type":"null"}],"title":"Item Value"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CoverageProviderListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/coverage/providers/{provider_id}/click":{"post":{"tags":["Coverage"],"summary":"Record Provider Click","description":"Log the tap through. This is the number worth having: not that someone\nwanted coverage, but that they went to a named carrier to get it.","operationId":"record_provider_click_api_v1_coverage_providers__provider_id__click_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"provider_id","in":"path","required":true,"schema":{"type":"integer","title":"Provider Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderClickRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/coverage/schedule/link":{"post":{"tags":["Coverage"],"summary":"Create Schedule Link","description":"Mint a signed, expiring link to this user's schedule.\n\nA link rather than an authenticated fetch because the artifact's job is to\nbe opened in a browser and forwarded to an insurer.","operationId":"create_schedule_link_api_v1_coverage_schedule_link_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScheduleLinkRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScheduleLinkResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/coverage/schedule/{token}":{"get":{"tags":["Coverage"],"summary":"View Schedule","description":"Render the schedule. Signed link only, expires after a week.","operationId":"view_schedule_api_v1_coverage_schedule__token__get","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/network/config":{"get":{"tags":["Network"],"summary":"Get Network Config","description":"Lane thresholds, copy, terminology and units, in the caller's vocabulary.\nThe app treats its compiled-in copy purely as an offline fallback.\n\nPassing `item_value` adds `cost_note` and `below_threshold` per lane, which\nis what turns \"1% to 2% of value\" into \"$105 to $210 a year for this ring\".\nOmitting it returns exactly what clients before 2.0.45 receive.","operationId":"get_network_config_api_v1_network_config_get","parameters":[{"name":"country","in":"query","required":false,"schema":{"anyOf":[{"type":"string","minLength":2,"maxLength":2},{"type":"null"}],"title":"Country"}},{"name":"item_value","in":"query","required":false,"schema":{"anyOf":[{"type":"number","minimum":0.0},{"type":"null"}],"description":"Anchor value of the piece, for per-piece costing","title":"Item Value"},"description":"Anchor value of the piece, for per-piece costing"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/network/professionals":{"get":{"tags":["Network"],"summary":"List Professionals","description":"Nearby professionals for a lane, plus the national cards, so the sheet\nalways has something to render. User coordinates are used for this query\nand logged only rounded; nothing user-located is persisted.","operationId":"list_professionals_api_v1_network_professionals_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"lane","in":"query","required":true,"schema":{"type":"string","description":"appraisal | sell | insurance","title":"Lane"},"description":"appraisal | sell | insurance"},{"name":"lat","in":"query","required":false,"schema":{"anyOf":[{"type":"number","maximum":90.0,"minimum":-90.0},{"type":"null"}],"title":"Lat"}},{"name":"lng","in":"query","required":false,"schema":{"anyOf":[{"type":"number","maximum":180.0,"minimum":-180.0},{"type":"null"}],"title":"Lng"}},{"name":"country","in":"query","required":false,"schema":{"anyOf":[{"type":"string","minLength":2,"maxLength":2},{"type":"null"}],"title":"Country"}},{"name":"postal_code","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":20},{"type":"null"}],"title":"Postal Code"}},{"name":"city","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}],"title":"City"}},{"name":"radius_km","in":"query","required":false,"schema":{"type":"number","maximum":320.0,"minimum":5.0,"default":80.0,"title":"Radius Km"}},{"name":"item_value","in":"query","required":false,"schema":{"anyOf":[{"type":"number","minimum":0.0},{"type":"null"}],"title":"Item Value"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":50,"minimum":1,"default":20,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NetworkProfessionalsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/network/professionals/{professional_id}/click":{"post":{"tags":["Network"],"summary":"Record Professional Click","description":"Log a tap through to a listing. Same contract as provider clicks: not\ndeduped, and the piece's value only attaches when the piece is the\ncaller's own.","operationId":"record_professional_click_api_v1_network_professionals__professional_id__click_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"professional_id","in":"path","required":true,"schema":{"type":"integer","title":"Professional Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProfessionalClickRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/network/leads":{"post":{"tags":["Network"],"summary":"Create Network Lead","description":"Ask for an introduction. Consent must be explicit; a lead against an\nunclaimed listing is held with no user data leaving the system.","operationId":"create_network_lead_api_v1_network_leads_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NetworkLeadCreate"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NetworkLeadResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/network/leads/mine":{"get":{"tags":["Network"],"summary":"List My Leads","description":"The user's introduction requests, newest first, for the Settings view.","operationId":"list_my_leads_api_v1_network_leads_mine_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/NetworkLeadListRow"},"type":"array","title":"Response List My Leads Api V1 Network Leads Mine Get"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/network/leads/{lead_id}":{"delete":{"tags":["Network"],"summary":"Withdraw Lead","description":"Withdraw a request that has not gone out yet. An email already\ndelivered cannot be unsent, and the endpoint says so.","operationId":"withdraw_lead_api_v1_network_leads__lead_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"lead_id","in":"path","required":true,"schema":{"type":"integer","title":"Lead Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/network/claim/{token}":{"get":{"tags":["Network"],"summary":"View Claim Page","operationId":"view_claim_page_api_v1_network_claim__token__get","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["Network"],"summary":"Submit Claim","operationId":"submit_claim_api_v1_network_claim__token__post","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/Body_submit_claim_api_v1_network_claim__token__post"}}}},"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/network/claim/{token}/remove":{"post":{"tags":["Network"],"summary":"Remove Listing","description":"The no-account removal path. One click, no questions.","operationId":"remove_listing_api_v1_network_claim__token__remove_post","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/network/directory":{"get":{"tags":["Network"],"summary":"Public Directory","description":"Public print of the map for the static site generator. Emails, notes\nand CRM linkage never appear here; suppressed rows are filtered.","operationId":"public_directory_api_v1_network_directory_get","parameters":[{"name":"country","in":"query","required":false,"schema":{"anyOf":[{"type":"string","minLength":2,"maxLength":2},{"type":"null"}],"title":"Country"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/insights":{"get":{"tags":["Insights"],"summary":"List Articles","description":"GET /api/v1/insights","operationId":"list_articles_api_v1_insights_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/ArticleResponse"},"type":"array","title":"Response List Articles Api V1 Insights Get"}}}}}}},"/api/v1/insights/featured":{"get":{"tags":["Insights"],"summary":"Get Featured Article","description":"GET /api/v1/insights/featured","operationId":"get_featured_article_api_v1_insights_featured_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArticleResponse"}}}}}}},"/api/v1/insights/{article_id}":{"get":{"tags":["Insights"],"summary":"Get Article","description":"GET /api/v1/insights/{id}","operationId":"get_article_api_v1_insights__article_id__get","parameters":[{"name":"article_id","in":"path","required":true,"schema":{"type":"string","title":"Article Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArticleResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/notifications":{"get":{"tags":["Notifications"],"summary":"List Notifications","description":"GET /api/v1/notifications?limit=&cursor=&include_read=\nThe caller's inbox, newest first, excluding dismissed and expired rows.\n\nCursor-paged rather than page/page_size (the convention elsewhere in this\nAPI) because this is the one prepend-heavy list we serve: producers insert\nat the top between a client's page 1 and page 2 requests, and offset paging\nwould then re-show rows the user already scrolled past. The cursor is an\nopaque (created_at, id) pair — treat it as a token, not a number.\n\n`unread_count` is returned on every page so the client can reconcile its\nbadge without a second call.","operationId":"list_notifications_api_v1_notifications_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":25,"title":"Limit"}},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cursor"}},{"name":"include_read","in":"query","required":false,"schema":{"type":"boolean","default":true,"title":"Include Read"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotificationFeedResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/notifications/unread-count":{"get":{"tags":["Notifications"],"summary":"Get Unread Count","description":"GET /api/v1/notifications/unread-count\nBadge count only. Cheap enough to call on every foreground.","operationId":"get_unread_count_api_v1_notifications_unread_count_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnreadCountResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/notifications/read-all":{"post":{"tags":["Notifications"],"summary":"Mark All Read","description":"POST /api/v1/notifications/read-all\nMark every visible unread row read. Idempotent: returns 0 when there was\nnothing to mark.\n\nDeclared before /{notification_id} so the literal path wins the match.","operationId":"mark_all_read_api_v1_notifications_read_all_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarkAllReadResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/notifications/{notification_id}/read":{"post":{"tags":["Notifications"],"summary":"Mark Read","description":"POST /api/v1/notifications/{id}/read\nMark one row read. Idempotent: re-reading keeps the original read_at.","operationId":"mark_read_api_v1_notifications__notification_id__read_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"notification_id","in":"path","required":true,"schema":{"type":"integer","title":"Notification Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/notifications/{notification_id}":{"delete":{"tags":["Notifications"],"summary":"Dismiss Notification","description":"DELETE /api/v1/notifications/{id}\nHide a row from the feed. Soft (dismissed_at) so the producer's\n(user_id, trigger_ref) dedupe still sees it and cannot resurrect it on the\nnext cron run. Idempotent.","operationId":"dismiss_notification_api_v1_notifications__notification_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"notification_id","in":"path","required":true,"schema":{"type":"integer","title":"Notification Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/board":{"get":{"tags":["Community Board"],"summary":"Get Board","description":"This week's ranked board. Public.\n\nOrdering is by computed score, not by stored rank, so the board reshuffles\nthe moment a vote lands rather than when a job next runs. That does mean\nsorting in Python: the whole week's live entries are loaded, scored, and\nsliced. At board volumes (tens of entries a week, capped by how many\npeople submit) this is far cheaper than the alternative of maintaining a\ndenormalised score column and eating a write amplification on every tap.\nIf a week ever breaks a few thousand entries, this is the thing to\nrevisit — not before.","operationId":"get_board_api_v1_board_get","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":50,"minimum":1,"default":10,"title":"Page Size"}},{"name":"week","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"ISO date of a past week's Monday","title":"Week"},"description":"ISO date of a past week's Monday"},{"name":"X-Device-Id","in":"header","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"X-Device-Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BoardListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/board/entries/{entry_id}":{"get":{"tags":["Community Board"],"summary":"Get Entry","description":"One entry with its full publishable piece. Public.\n\nThis exists because `GET /gems/{id}/details` is owner-scoped — it resolves\nby user_id or device_id and returns 404 to everyone else — so there is no\nway for a non-owner to read a piece they just tapped on the board without\nit.","operationId":"get_entry_api_v1_board_entries__entry_id__get","parameters":[{"name":"entry_id","in":"path","required":true,"schema":{"type":"integer","title":"Entry Id"}},{"name":"X-Device-Id","in":"header","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"X-Device-Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BoardEntryOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Community Board"],"summary":"Remove Entry","description":"Owner pulls their piece off the board.\n\nTakes the thread with it. Someone withdrawing a piece is withdrawing the\nconversation about it too — leaving an orphaned thread of strangers\ndiscussing a photo the owner just retracted would be the worst possible\nreading of \"you can remove it\".\n\nThe row itself is kept (status flips to 'removed') so the partial unique\nindex can let the same piece go back up later, and so a takedown is\nauditable.","operationId":"remove_entry_api_v1_board_entries__entry_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"entry_id","in":"path","required":true,"schema":{"type":"integer","title":"Entry Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SimpleOk"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/board/eligible":{"get":{"tags":["Community Board"],"summary":"List Eligible","description":"The caller's own saved pieces and whether each may be submitted.\n\nPowers the \"put one on the board\" picker. Returns ineligible pieces too,\nwith the reason, because a picker that silently omits half someone's\ncollection reads as a bug.","operationId":"list_eligible_api_v1_board_eligible_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EligibleListResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/board/entries":{"post":{"tags":["Community Board"],"summary":"Submit Entry","description":"Publish one of the caller's own pieces to this week's board.\n\nThe consent boundary of the whole feature lives in this handler. Ownership\nis checked against user_id directly rather than through any device\nfallback: publishing is not something that should ever happen from a\nsession that cannot prove whose piece it is.","operationId":"submit_entry_api_v1_board_entries_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubmitEntryRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BoardEntryOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/board/entries/{entry_id}/cover":{"patch":{"tags":["Community Board"],"summary":"Set Cover","description":"Owner changes which photo fronts their card.","operationId":"set_cover_api_v1_board_entries__entry_id__cover_patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"entry_id","in":"path","required":true,"schema":{"type":"integer","title":"Entry Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetCoverRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BoardEntryOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/board/entries/{entry_id}/vote":{"post":{"tags":["Community Board"],"summary":"Cast Vote","description":"One tap. No account required.\n\nAn anonymous caller must send X-Device-Id — without either an identity or\na device there is nothing to enforce one-vote-per-voter against, and an\nunkeyed vote endpoint is just a counter anyone can drive.","operationId":"cast_vote_api_v1_board_entries__entry_id__vote_post","parameters":[{"name":"entry_id","in":"path","required":true,"schema":{"type":"integer","title":"Entry Id"}},{"name":"X-Device-Id","in":"header","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"X-Device-Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VoteResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Community Board"],"summary":"Retract Vote","operationId":"retract_vote_api_v1_board_entries__entry_id__vote_delete","parameters":[{"name":"entry_id","in":"path","required":true,"schema":{"type":"integer","title":"Entry Id"}},{"name":"X-Device-Id","in":"header","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"X-Device-Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VoteResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/board/entries/{entry_id}/comments":{"get":{"tags":["Community Board"],"summary":"List Comments","description":"The thread. Public to read.\n\nComments from people the caller has blocked are filtered here rather than\ndeleted — a block hides someone from your view without touching their\ncontent or telling them anything.","operationId":"list_comments_api_v1_board_entries__entry_id__comments_get","parameters":[{"name":"entry_id","in":"path","required":true,"schema":{"type":"integer","title":"Entry Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BoardCommentListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["Community Board"],"summary":"Create Comment","description":"Post to the thread. Auth required, and moderated before it is stored.\n\nThe moderation call happens BEFORE the insert, and a moderation outage is\na 503, not a publish. See board_service.moderate_text — failing open would\nquietly disable the content filter that App Store 1.2 requires, with\nnothing in the product looking wrong while it happened.","operationId":"create_comment_api_v1_board_entries__entry_id__comments_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"entry_id","in":"path","required":true,"schema":{"type":"integer","title":"Entry Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommentRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BoardCommentOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/board/comments/{comment_id}":{"delete":{"tags":["Community Board"],"summary":"Delete Comment","description":"Remove a comment. Author or the piece's owner.\n\nGiving the owner delete rights on their own thread matters: they are the\nperson whose photograph is on the card, and the alternative is that\nclearing something unpleasant off their own piece requires our\nintervention.","operationId":"delete_comment_api_v1_board_comments__comment_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"comment_id","in":"path","required":true,"schema":{"type":"integer","title":"Comment Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SimpleOk"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/board/report":{"post":{"tags":["Community Board"],"summary":"Report Content","description":"Flag an entry or a comment for review.","operationId":"report_content_api_v1_board_report_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReportRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SimpleOk"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/board/block":{"post":{"tags":["Community Board"],"summary":"Block Member","description":"Stop seeing a member's comments.\n\nIdentified by the comment being looked at, or by a raw user id for callers\nthat already hold one. The comment path exists so the app never needs an\nauthor id: the public comment payload deliberately carries none, and an\nenumerable member id on an unauthenticated endpoint is not something a\nblock button needs in order to work.","operationId":"block_member_api_v1_board_block_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BlockRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SimpleOk"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/board/block/{user_id}":{"delete":{"tags":["Community Board"],"summary":"Unblock Member","operationId":"unblock_member_api_v1_board_block__user_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"integer","title":"User Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SimpleOk"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/assistant/capabilities":{"get":{"tags":["Collection Assistant"],"summary":"Get Capabilities","operationId":"get_capabilities_api_v1_assistant_capabilities_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"X-App-Version","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-App-Version"}},{"name":"X-Agent-Cards","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Agent-Cards"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CapabilitiesOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/assistant/gems/{gem_id}":{"get":{"tags":["Collection Assistant"],"summary":"Get Piece State","operationId":"get_piece_state_api_v1_assistant_gems__gem_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"gem_id","in":"path","required":true,"schema":{"type":"integer","title":"Gem Id"}},{"name":"X-App-Version","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-App-Version"}},{"name":"X-Agent-Cards","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Agent-Cards"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PieceStateOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/assistant/gems/{gem_id}/confirm-identity":{"post":{"tags":["Collection Assistant"],"summary":"Confirm Identity","description":"The owner answers \"Is this a sapphire?\" with yes. A different answer\ngoes through PATCH /gems/{id}/identification, the real correction.","operationId":"confirm_identity_api_v1_assistant_gems__gem_id__confirm_identity_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"gem_id","in":"path","required":true,"schema":{"type":"integer","title":"Gem Id"}},{"name":"X-App-Version","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-App-Version"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PieceStateOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/assistant/summary":{"get":{"tags":["Collection Assistant"],"summary":"Get Summary","operationId":"get_summary_api_v1_assistant_summary_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"X-App-Version","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-App-Version"}},{"name":"X-Agent-Cards","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Agent-Cards"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SummaryOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/assistant/requests":{"post":{"tags":["Collection Assistant"],"summary":"Create Reminder","operationId":"create_reminder_api_v1_assistant_requests_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"X-App-Version","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-App-Version"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReminderIn"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReminderOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/assistant/requests/{request_id}":{"patch":{"tags":["Collection Assistant"],"summary":"Update Reminder","operationId":"update_reminder_api_v1_assistant_requests__request_id__patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"request_id","in":"path","required":true,"schema":{"type":"integer","title":"Request Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateReminderIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReminderOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/assistant/findings/{finding_id}":{"get":{"tags":["Collection Assistant"],"summary":"Get Finding","operationId":"get_finding_api_v1_assistant_findings__finding_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"finding_id","in":"path","required":true,"schema":{"type":"integer","title":"Finding Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FindingDetailOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/assistant/findings/{finding_id}/feedback":{"post":{"tags":["Collection Assistant"],"summary":"Post Feedback","operationId":"post_feedback_api_v1_assistant_findings__finding_id__feedback_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"finding_id","in":"path","required":true,"schema":{"type":"integer","title":"Finding Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeedbackIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FindingOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/assistant/findings/{finding_id}/source-opened":{"post":{"tags":["Collection Assistant"],"summary":"Post Source Opened","description":"The owner opened a card's source link [LNK-LIKEYOURS].","operationId":"post_source_opened_api_v1_assistant_findings__finding_id__source_opened_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"finding_id","in":"path","required":true,"schema":{"type":"integer","title":"Finding Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FindingOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/assistant/gems/{gem_id}/understanding":{"get":{"tags":["Collection Assistant"],"summary":"Get Understanding","description":"The piece's facts with where each came from, what is still open, and\nwhat the piece is to its owner.","operationId":"get_understanding_api_v1_assistant_gems__gem_id__understanding_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"gem_id","in":"path","required":true,"schema":{"type":"integer","title":"Gem Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnderstandingOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/assistant/gems/{gem_id}/relationship":{"patch":{"tags":["Collection Assistant"],"summary":"Set Relationship","description":"Yours, considering, no longer yours; worn daily; no shopping\nsuggestions. Only the fields sent change.","operationId":"set_relationship_api_v1_assistant_gems__gem_id__relationship_patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"gem_id","in":"path","required":true,"schema":{"type":"integer","title":"Gem Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RelationshipIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnderstandingOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/assistant/gems/{gem_id}/facts/{key}":{"put":{"tags":["Collection Assistant"],"summary":"Correct Fact","description":"The owner rewords a fact they told us (maker, metal, treatment,\norigin) [LNK-AGENT C4]. Removing one is POST /learned/forget with the\nfact's ids.","operationId":"correct_fact_api_v1_assistant_gems__gem_id__facts__key__put","security":[{"HTTPBearer":[]}],"parameters":[{"name":"gem_id","in":"path","required":true,"schema":{"type":"integer","title":"Gem Id"}},{"name":"key","in":"path","required":true,"schema":{"type":"string","title":"Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FactIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnderstandingOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/assistant/agent/switch":{"get":{"tags":["Collection Assistant"],"summary":"Get Agent Switch","operationId":"get_agent_switch_api_v1_assistant_agent_switch_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentSwitchOut"}}}}},"security":[{"HTTPBearer":[]}]},"put":{"tags":["Collection Assistant"],"summary":"Set Agent Switch","description":"Turn the Collection Agent on or off. On needs granted notification\npermission and a push token; without them it answers 409 push_required\nwith the reason, and nothing is stored.","operationId":"set_agent_switch_api_v1_assistant_agent_switch_put","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentSwitchIn"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentSwitchOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/assistant/agent/switch/check":{"post":{"tags":["Collection Assistant"],"summary":"Check Agent Switch","description":"The app reports the OS notification permission on open.","operationId":"check_agent_switch_api_v1_assistant_agent_switch_check_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentSwitchCheckIn"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentSwitchOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/assistant/agent/switch/asked":{"post":{"tags":["Collection Assistant"],"summary":"Asked Agent Switch","description":"The one-time ask was shown and dismissed without a choice.","operationId":"asked_agent_switch_api_v1_assistant_agent_switch_asked_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentSwitchOut"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/assistant/gems/{gem_id}/identity/keep-scan":{"post":{"tags":["Collection Assistant"],"summary":"Keep Scan Identity","description":"The owner said one stone, the scan read another, and the owner sides\nwith the scan: their earlier statements stop naming the piece. (Siding\nwith their own word is the real correction, PATCH /gems/{id}/identification.)","operationId":"keep_scan_identity_api_v1_assistant_gems__gem_id__identity_keep_scan_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"gem_id","in":"path","required":true,"schema":{"type":"integer","title":"Gem Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnderstandingOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/assistant/preferences":{"get":{"tags":["Collection Assistant"],"summary":"Get Preferences","description":"What was learned from what the owner said and did, in plain words.","operationId":"get_preferences_api_v1_assistant_preferences_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PreferencesOut"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/assistant/learned/forget":{"post":{"tags":["Collection Assistant"],"summary":"Forget Learned","description":"Remove something learned. Undoes exactly what it taught.","operationId":"forget_learned_api_v1_assistant_learned_forget_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForgetIn"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PreferencesOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/assistant/gems/{gem_id}/record":{"get":{"tags":["Piece Record"],"summary":"Get Record","operationId":"get_record_api_v1_assistant_gems__gem_id__record_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"gem_id","in":"path","required":true,"schema":{"type":"integer","title":"Gem Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["Piece Record"],"summary":"Patch Record","operationId":"patch_record_api_v1_assistant_gems__gem_id__record_patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"gem_id","in":"path","required":true,"schema":{"type":"integer","title":"Gem Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPatch"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/assistant/gems/{gem_id}/record/entries":{"post":{"tags":["Piece Record"],"summary":"Add Entry","operationId":"add_entry_api_v1_assistant_gems__gem_id__record_entries_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"gem_id","in":"path","required":true,"schema":{"type":"integer","title":"Gem Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EntryIn"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/assistant/gems/{gem_id}/record/entries/{entry_id}":{"patch":{"tags":["Piece Record"],"summary":"Edit Entry","operationId":"edit_entry_api_v1_assistant_gems__gem_id__record_entries__entry_id__patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"gem_id","in":"path","required":true,"schema":{"type":"integer","title":"Gem Id"}},{"name":"entry_id","in":"path","required":true,"schema":{"type":"integer","title":"Entry Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EntryPatch"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Piece Record"],"summary":"Remove Entry","operationId":"remove_entry_api_v1_assistant_gems__gem_id__record_entries__entry_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"gem_id","in":"path","required":true,"schema":{"type":"integer","title":"Gem Id"}},{"name":"entry_id","in":"path","required":true,"schema":{"type":"integer","title":"Entry Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/assistant/gems/{gem_id}/record/suggestions/dismiss":{"post":{"tags":["Piece Record"],"summary":"Dismiss Suggestions","operationId":"dismiss_suggestions_api_v1_assistant_gems__gem_id__record_suggestions_dismiss_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"gem_id","in":"path","required":true,"schema":{"type":"integer","title":"Gem Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DismissIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/assistant/gems/{gem_id}/card/preview":{"post":{"tags":["Piece Record"],"summary":"Preview Card","operationId":"preview_card_api_v1_assistant_gems__gem_id__card_preview_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"gem_id","in":"path","required":true,"schema":{"type":"integer","title":"Gem Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CardSelection"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CardContentOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/assistant/gems/{gem_id}/card/links":{"post":{"tags":["Piece Record"],"summary":"Create Link","operationId":"create_link_api_v1_assistant_gems__gem_id__card_links_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"gem_id","in":"path","required":true,"schema":{"type":"integer","title":"Gem Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkIn"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkCreatedOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/assistant/gems/{gem_id}/card/links/{link_id}":{"delete":{"tags":["Piece Record"],"summary":"Revoke Link","operationId":"revoke_link_api_v1_assistant_gems__gem_id__card_links__link_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"gem_id","in":"path","required":true,"schema":{"type":"integer","title":"Gem Id"}},{"name":"link_id","in":"path","required":true,"schema":{"type":"integer","title":"Link Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/subscriptions/plans":{"get":{"tags":["Subscriptions","Subscriptions"],"summary":"Get Subscription Plans","description":"Get all available subscription plans with pricing options (PUBLIC endpoint).\n\nReturns only active and visible plans with their pricing options.\n`catalog=tiers` (LNK-SCANTIERS) returns the paid tier plans instead. They\nare hidden from the default listing because shipped builds price every\nlisted plan from the legacy unlimited products.\nThis endpoint doesn't require authentication.","operationId":"get_subscription_plans_api_v1_subscriptions_plans_get","parameters":[{"name":"catalog","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"'tiers' returns the capped Premium + Collector plans","title":"Catalog"},"description":"'tiers' returns the capped Premium + Collector plans"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/PlanResponse"},"title":"Response Get Subscription Plans Api V1 Subscriptions Plans Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/subscriptions/status":{"get":{"tags":["Subscriptions","Subscriptions"],"summary":"Get Quick Subscription Status","description":"**🚀 QUICK STATUS CHECK - Supports both authenticated and device-based users**\n\nGet lightweight subscription status - perfect for:\n- App header (showing plan badge: \"Free\" or \"Premium\")\n- Dashboard widgets\n- Quick checks before user actions\n- Displaying remaining scans/gems counters\n\n**Access Methods:**\n- **With Token**: Returns user subscription status (authenticated)\n- **With X-Device-Id**: Returns device scan status (anonymous)\n- **With Both**: Returns user status (token takes priority)\n- **With Neither**: Returns 401 error\n\n**Response includes:**\n- `plan_type`: \"free\" or \"premium\"\n- `is_active`: true/false\n- `scans_remaining`: number or \"unlimited\"\n- `collection_slots_remaining`: number or \"unlimited\"\n\n**Example Usage:**\n```javascript\n// Authenticated user\nconst status = await fetch('/api/v1/subscriptions/status', {\n  headers: { 'Authorization': `Bearer ${token}` }\n}).then(r => r.json());\n\n// Anonymous user with device tracking\nconst status = await fetch('/api/v1/subscriptions/status', {\n  headers: { 'X-Device-Id': deviceId }\n}).then(r => r.json());\n\n// Use for UI\nif (status.plan_type === 'free') {\n  showUpgradeBanner();\n}\nif (status.scans_remaining === 0) {\n  disableScanButton();\n}\n```\n\n**Fast & Lightweight** - Only returns essential info for UI state.","operationId":"get_quick_subscription_status_api_v1_subscriptions_status_get","parameters":[{"name":"X-Device-Id","in":"header","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"X-Device-Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuickSubscriptionStatusResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/subscriptions/plan-details":{"get":{"tags":["Subscriptions","Subscriptions"],"summary":"Get User Plan Details","description":"**📋 COMPLETE PLAN DETAILS - Use this for detailed displays**\n\nGet full plan information including:\n- All plan features (categorized)\n- Usage statistics\n- Billing information\n- Plan metadata\n\n**Perfect for:**\n- Account/Settings page\n- Plan comparison modals\n- Upgrade prompts with feature lists\n- Subscription management page\n\n**Response includes:**\n- Full plan details with all features\n- Usage stats (scans used, gems count)\n- Billing info (price, next billing date)\n- All plan features categorized (Scanning, Analysis, Collection, etc.)\n\n**Example Usage:**\n```javascript\n// Call when user opens settings or subscription page\nconst details = await fetch('/api/v1/subscriptions/plan-details', {\n  headers: { 'Authorization': `Bearer ${token}` }\n}).then(r => r.json());\n\n// Display full plan info\nconsole.log(details.plan_display_name); // \"Free\" or \"Premium\"\nconsole.log(details.features); // All categorized features\nconsole.log(details.price); // \"$29.99/monthly\"\n```\n\n**More Complete** - Returns all plan information for detailed displays.","operationId":"get_user_plan_details_api_v1_subscriptions_plan_details_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserPlanDetailsResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/subscriptions/status/detailed":{"get":{"tags":["Subscriptions","Subscriptions"],"summary":"Get Detailed Subscription Status","description":"Get detailed subscription status including all limits and usage.\n\nReturns comprehensive information about:\n- Current plan and status\n- Scan usage and limits\n- Collection count and limits\n- Billing information\n- Next billing date\n\nThis is the recommended endpoint for displaying user subscription status in the app.","operationId":"get_detailed_subscription_status_api_v1_subscriptions_status_detailed_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionStatusDetailedResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/subscriptions/cancel-feedback":{"post":{"tags":["Subscriptions","Subscriptions"],"summary":"Submit Cancel Feedback","description":"[LNK-CANCELWHY] One optional answer from the in-app Cancel button,\nasked before the store's subscription page opens. Never blocks the cancel.","operationId":"submit_cancel_feedback_api_v1_subscriptions_cancel_feedback_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"X-App-Version","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-App-Version"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CancelFeedbackRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/subscriptions/sync":{"post":{"tags":["Subscriptions","Subscriptions"],"summary":"Sync Subscription Status","description":"Sync subscription status with RevenueCat.\n\nCall this on app launch to ensure local DB matches RevenueCat state.\nUseful if webhooks were missed or for initial sync.\n\n**When to call:**\n- App launch/foreground\n- After completing a purchase in the app\n- When subscription status seems stale\n\n**Returns:**\nQuick subscription status with updated data from RevenueCat.","operationId":"sync_subscription_status_api_v1_subscriptions_sync_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuickSubscriptionStatusResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/collection/insights":{"get":{"tags":["Collection Insights"],"summary":"Collection Insights","description":"Aggregated insight lenses over the caller's saved collection.\n\nEvery top-level block is independently nullable — a lens failure degrades\nthat block to null, never a 500.","operationId":"collection_insights_api_v1_collection_insights_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectionInsightsResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/analytics/collection-value":{"get":{"tags":["Analytics","Analytics"],"summary":"Get Collection Value","description":"GET /api/v1/analytics/collection-value\nGet collection value over time with trend analysis.","operationId":"get_collection_value_api_v1_analytics_collection_value_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"period","in":"query","required":false,"schema":{"type":"string","default":"30d","title":"Period"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/analytics/performance":{"get":{"tags":["Analytics","Analytics"],"summary":"Get Performance Metrics","description":"GET /api/v1/analytics/performance\nGet portfolio performance metrics and insights.","operationId":"get_performance_metrics_api_v1_analytics_performance_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/admin/plans":{"post":{"tags":["Admin - Plans","Admin - Plans"],"summary":"Create Plan","description":"Create a new subscription plan.\n\nFor now: Public endpoint (no admin auth)\nFuture: Add admin role check","operationId":"create_plan_api_v1_admin_plans_post","parameters":[{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlanCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlanResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["Admin - Plans","Admin - Plans"],"summary":"List Plans","description":"Get all plans (with options)","operationId":"list_plans_api_v1_admin_plans_get","parameters":[{"name":"include_inactive","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Include Inactive"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/PlanResponse"},"title":"Response List Plans Api V1 Admin Plans Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/plans/{plan_id}":{"get":{"tags":["Admin - Plans","Admin - Plans"],"summary":"Get Plan","description":"Get plan by ID","operationId":"get_plan_api_v1_admin_plans__plan_id__get","parameters":[{"name":"plan_id","in":"path","required":true,"schema":{"type":"integer","title":"Plan Id"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlanResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["Admin - Plans","Admin - Plans"],"summary":"Update Plan","description":"Update plan","operationId":"update_plan_api_v1_admin_plans__plan_id__put","parameters":[{"name":"plan_id","in":"path","required":true,"schema":{"type":"integer","title":"Plan Id"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlanUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlanResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Admin - Plans","Admin - Plans"],"summary":"Delete Plan","description":"Delete plan (soft delete - sets is_active=False).\nCascade deletes all plan options.","operationId":"delete_plan_api_v1_admin_plans__plan_id__delete","parameters":[{"name":"plan_id","in":"path","required":true,"schema":{"type":"integer","title":"Plan Id"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/plans/{plan_id}/options":{"post":{"tags":["Admin - Plans","Admin - Plans"],"summary":"Create Plan Option","description":"Create a billing option for a plan","operationId":"create_plan_option_api_v1_admin_plans__plan_id__options_post","parameters":[{"name":"plan_id","in":"path","required":true,"schema":{"type":"integer","title":"Plan Id"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlanOptionCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlanOptionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/plans/{plan_id}/options/{option_id}":{"put":{"tags":["Admin - Plans","Admin - Plans"],"summary":"Update Plan Option","description":"Update plan option","operationId":"update_plan_option_api_v1_admin_plans__plan_id__options__option_id__put","parameters":[{"name":"plan_id","in":"path","required":true,"schema":{"type":"integer","title":"Plan Id"}},{"name":"option_id","in":"path","required":true,"schema":{"type":"integer","title":"Option Id"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlanOptionUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlanOptionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Admin - Plans","Admin - Plans"],"summary":"Delete Plan Option","description":"Delete plan option (soft delete)","operationId":"delete_plan_option_api_v1_admin_plans__plan_id__options__option_id__delete","parameters":[{"name":"plan_id","in":"path","required":true,"schema":{"type":"integer","title":"Plan Id"}},{"name":"option_id","in":"path","required":true,"schema":{"type":"integer","title":"Option Id"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/test/users/list":{"get":{"tags":["Admin - Test Users","Admin - Test Users"],"summary":"List All Users","description":"List all users with their subscription details.\n\n**Testing endpoint** - Returns user info including:\n- User details (name, mobile, email)\n- Current subscription plan\n- Subscription status\n- Premium status","operationId":"list_all_users_api_v1_admin_test_users_list_get","parameters":[{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/UserSubscriptionInfo"},"title":"Response List All Users Api V1 Admin Test Users List Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/test/users/{user_id}/make-premium":{"post":{"tags":["Admin - Test Users","Admin - Test Users"],"summary":"Make User Premium","description":"Make a user premium member for testing.\n\n**Testing endpoint** - This will:\n1. Find or create premium plan\n2. Cancel any existing active subscriptions\n3. Create new active premium subscription\n4. Set unlimited scans and collection","operationId":"make_user_premium_api_v1_admin_test_users__user_id__make_premium_post","parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"integer","title":"User Id"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSubscriptionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/test/users/{user_id}/revert-to-free":{"post":{"tags":["Admin - Test Users","Admin - Test Users"],"summary":"Revert User To Free","description":"Revert user to free plan for testing.\n\n**Testing endpoint** - This will:\n1. Find or create free plan\n2. Cancel any existing active subscriptions\n3. Create new active free subscription\n4. Apply free plan limits","operationId":"revert_user_to_free_api_v1_admin_test_users__user_id__revert_to_free_post","parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"integer","title":"User Id"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSubscriptionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/scans/{gem_id}":{"get":{"tags":["Admin - Scans","Admin - Scans"],"summary":"Get Scan Admin","description":"Return the full GemstoneResponse for a single scan, including\n`value_breakdown`, `market_insights`, `user_id` — all the fields stripped\non the public `/gems/global-scans` endpoint.","operationId":"get_scan_admin_api_v1_admin_scans__gem_id__get","parameters":[{"name":"gem_id","in":"path","required":true,"schema":{"type":"integer","title":"Gem Id"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GemstoneResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/scans":{"get":{"tags":["Admin - Scans","Admin - Scans"],"summary":"List Scans Admin","description":"List recent scans across all users. Filter by `user_id` when triaging a\nspecific consumer's history. `page_size` capped at 100.","operationId":"list_scans_admin_api_v1_admin_scans_get","parameters":[{"name":"user_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"User Id"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","default":20,"title":"Page Size"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GemListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/pricing/grid/populate":{"post":{"tags":["Admin - Pricing","Admin - Pricing"],"summary":"Populate Grid","description":"Rebuild reference grid cells from price_observations.\n\nQuery params:\n    species: optional. When set, only this species is rebuilt. When omitted,\n             every species with a rubric on disk is rebuilt.\n\nReturns per-species result rows. The job runs synchronously (single-species\nis seconds; all-species is typically under a minute for the current\nobservation volume).","operationId":"populate_grid_api_v1_admin_pricing_grid_populate_post","parameters":[{"name":"species","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Species"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/pricing/grid/rubrics":{"get":{"tags":["Admin - Pricing","Admin - Pricing"],"summary":"List Rubrics","description":"Inspect which species have a rubric on disk. Useful to confirm what\n/grid/populate (no args) will operate on.","operationId":"list_rubrics_api_v1_admin_pricing_grid_rubrics_get","parameters":[{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/pricing/grades/backfill":{"post":{"tags":["Admin - Pricing","Admin - Pricing"],"summary":"Backfill Canonical Grades","description":"Normalize free-text JSON estimates into canonical grade columns.\n\nReturns a per-row report plus an aggregate count of populated cells.\nFor large backfills, call repeatedly with increasing offset until\nrows_processed < limit.","operationId":"backfill_canonical_grades_api_v1_admin_pricing_grades_backfill_post","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":2000,"minimum":1,"description":"Max rows this call","default":200,"title":"Limit"},"description":"Max rows this call"},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"description":"Skip this many rows","default":0,"title":"Offset"},"description":"Skip this many rows"},{"name":"force","in":"query","required":false,"schema":{"type":"boolean","description":"Overwrite existing canonical values","default":false,"title":"Force"},"description":"Overwrite existing canonical values"},{"name":"species","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Restrict to one species","title":"Species"},"description":"Restrict to one species"},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/notifications/broadcast":{"post":{"tags":["Admin - Notifications","Admin - Notifications"],"summary":"Broadcast Push","operationId":"broadcast_push_api_v1_admin_notifications_broadcast_post","parameters":[{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BroadcastRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/promo/codes":{"post":{"tags":["Admin - Promo Codes","Admin - Promo Codes"],"summary":"Mint Promo Codes","description":"Mint one or more promo codes.","operationId":"mint_promo_codes_api_v1_admin_promo_codes_post","parameters":[{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PromoMintRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PromoMintResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["Admin - Promo Codes","Admin - Promo Codes"],"summary":"List Promo Codes","description":"List codes, newest first — use this to see what has been claimed.","operationId":"list_promo_codes_api_v1_admin_promo_codes_get","parameters":[{"name":"campaign","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Campaign"}},{"name":"active_only","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Active Only"}},{"name":"unredeemed_only","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Unredeemed Only"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":1000,"minimum":1,"default":200,"title":"Limit"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/PromoCodeResponse"},"title":"Response List Promo Codes Api V1 Admin Promo Codes Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/promo/grant":{"post":{"tags":["Admin - Promo Codes","Admin - Promo Codes"],"summary":"Grant Premium To Email","description":"Comp an email address.\n\nIf they already have an account, premium turns on immediately. If not, the\nreturned code is reserved for that address and applies the moment they sign\nup — so an outreach reply can be honoured before the person exists as a user.","operationId":"grant_premium_to_email_api_v1_admin_promo_grant_post","parameters":[{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PromoGrantRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PromoGrantResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/promo/codes/{code}/deactivate":{"post":{"tags":["Admin - Promo Codes","Admin - Promo Codes"],"summary":"Deactivate Promo Code","description":"Kill a code. Already-granted premium is untouched.","operationId":"deactivate_promo_code_api_v1_admin_promo_codes__code__deactivate_post","parameters":[{"name":"code","in":"path","required":true,"schema":{"type":"string","title":"Code"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PromoCodeResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/board/reports":{"get":{"tags":["Admin - Community Board","Admin - Community Board"],"summary":"List Reports","operationId":"list_reports_api_v1_admin_board_reports_get","parameters":[{"name":"include_resolved","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Include Resolved"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":100,"title":"Limit"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReportListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/board/reports/{report_id}/resolve":{"post":{"tags":["Admin - Community Board","Admin - Community Board"],"summary":"Resolve Report","operationId":"resolve_report_api_v1_admin_board_reports__report_id__resolve_post","parameters":[{"name":"report_id","in":"path","required":true,"schema":{"type":"integer","title":"Report Id"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResolveRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResolveResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/board/entries/{entry_id}":{"get":{"tags":["Admin - Community Board","Admin - Community Board"],"summary":"Inspect Entry","description":"Full entry state including removed/blocked ones, for working a report.","operationId":"inspect_entry_api_v1_admin_board_entries__entry_id__get","parameters":[{"name":"entry_id","in":"path","required":true,"schema":{"type":"integer","title":"Entry Id"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/assistant/review":{"get":{"tags":["Admin - Collection Assistant"],"summary":"Review Queue","operationId":"review_queue_api_v1_admin_assistant_review_get","parameters":[{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/assistant/review/{finding_id}":{"post":{"tags":["Admin - Collection Assistant"],"summary":"Review","operationId":"review_api_v1_admin_assistant_review__finding_id__post","parameters":[{"name":"finding_id","in":"path","required":true,"schema":{"type":"integer","title":"Finding Id"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReviewIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/assistant/stats":{"get":{"tags":["Admin - Collection Assistant"],"summary":"Stats","description":"Evidence for the activation gates: usefulness, cost per useful finding.","operationId":"stats_api_v1_admin_assistant_stats_get","parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","default":30,"title":"Days"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/coverage/intents":{"get":{"tags":["Admin - Coverage","Admin - Coverage"],"summary":"List Coverage Intents","operationId":"list_coverage_intents_api_v1_admin_coverage_intents_get","parameters":[{"name":"kind","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"coverage | appraisal","title":"Kind"},"description":"coverage | appraisal"},{"name":"days","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","maximum":365,"minimum":1},{"type":"null"}],"title":"Days"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":1000,"minimum":1,"default":200,"title":"Limit"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminCoverageIntentsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/network/professionals":{"get":{"tags":["Admin - Network","Admin - Network"],"summary":"List Professionals","operationId":"list_professionals_api_v1_admin_network_professionals_get","parameters":[{"name":"country","in":"query","required":false,"schema":{"anyOf":[{"type":"string","minLength":2,"maxLength":2},{"type":"null"}],"title":"Country"}},{"name":"claim_status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Claim Status"}},{"name":"source","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source"}},{"name":"q","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}],"title":"Q"}},{"name":"include_suppressed","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Include Suppressed"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":1000,"minimum":1,"default":200,"title":"Limit"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["Admin - Network","Admin - Network"],"summary":"Create Professional","operationId":"create_professional_api_v1_admin_network_professionals_post","parameters":[{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminProfessionalUpsert"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/network/professionals/{professional_id}":{"patch":{"tags":["Admin - Network","Admin - Network"],"summary":"Update Professional","operationId":"update_professional_api_v1_admin_network_professionals__professional_id__patch","parameters":[{"name":"professional_id","in":"path","required":true,"schema":{"type":"integer","title":"Professional Id"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminProfessionalUpsert"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/network/leads":{"get":{"tags":["Admin - Network","Admin - Network"],"summary":"List Leads","operationId":"list_leads_api_v1_admin_network_leads_get","parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},{"name":"lane","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lane"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":1000,"minimum":1,"default":200,"title":"Limit"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/network/leads/{lead_id}/status":{"patch":{"tags":["Admin - Network","Admin - Network"],"summary":"Update Lead Status","operationId":"update_lead_status_api_v1_admin_network_leads__lead_id__status_patch","parameters":[{"name":"lead_id","in":"path","required":true,"schema":{"type":"integer","title":"Lead Id"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminLeadStatusUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/network/claims":{"get":{"tags":["Admin - Network","Admin - Network"],"summary":"List Claims","operationId":"list_claims_api_v1_admin_network_claims_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":1000,"minimum":1,"default":200,"title":"Limit"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/release-notes":{"post":{"tags":["Admin - Release Notes","Admin - Release Notes"],"summary":"Create Release Note","operationId":"create_release_note_api_v1_admin_release_notes_post","parameters":[{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseNoteCreate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["Admin - Release Notes","Admin - Release Notes"],"summary":"List Release Notes","operationId":"list_release_notes_api_v1_admin_release_notes_get","parameters":[{"name":"published_only","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Published Only"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/release-notes/{note_id}":{"patch":{"tags":["Admin - Release Notes","Admin - Release Notes"],"summary":"Update Release Note","operationId":"update_release_note_api_v1_admin_release_notes__note_id__patch","parameters":[{"name":"note_id","in":"path","required":true,"schema":{"type":"integer","title":"Note Id"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseNoteUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Admin - Release Notes","Admin - Release Notes"],"summary":"Delete Release Note","operationId":"delete_release_note_api_v1_admin_release_notes__note_id__delete","parameters":[{"name":"note_id","in":"path","required":true,"schema":{"type":"integer","title":"Note Id"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/agent/review/samples":{"get":{"tags":["Admin - Collection Agent Review"],"summary":"Samples","operationId":"samples_api_v1_admin_agent_review_samples_get","parameters":[{"name":"batch","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Batch"}},{"name":"kind","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Kind"}},{"name":"pending","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Pending"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/agent/review/{sample_id}":{"post":{"tags":["Admin - Collection Agent Review"],"summary":"Verdict","operationId":"verdict_api_v1_admin_agent_review__sample_id__post","parameters":[{"name":"sample_id","in":"path","required":true,"schema":{"type":"integer","title":"Sample Id"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerdictIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/agent/care-review/entries":{"get":{"tags":["Admin - Collection Agent Review"],"summary":"Care Entries","operationId":"care_entries_api_v1_admin_agent_care_review_entries_get","parameters":[{"name":"bank","in":"query","required":false,"schema":{"enum":["care","refresh","detail","story","tradition","collection"],"type":"string","default":"care","title":"Bank"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/agent/care-review/check":{"post":{"tags":["Admin - Collection Agent Review"],"summary":"Care Check","operationId":"care_check_api_v1_admin_agent_care_review_check_post","parameters":[{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CareCheckIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/agent/condition-review/notes":{"get":{"tags":["Admin - Collection Agent Review"],"summary":"Condition Notes","operationId":"condition_notes_api_v1_admin_agent_condition_review_notes_get","parameters":[{"name":"todo","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Todo"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/agent/condition-review/check":{"post":{"tags":["Admin - Collection Agent Review"],"summary":"Condition Check","operationId":"condition_check_api_v1_admin_agent_condition_review_check_post","parameters":[{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConditionCheckIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/agent/moments/import":{"post":{"tags":["Admin - Moment Bank"],"summary":"Import Moments","operationId":"import_moments_api_v1_admin_agent_moments_import_post","parameters":[{"name":"x-moments-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Moments-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/agent/moments/requests":{"get":{"tags":["Admin - Moment Bank"],"summary":"Research Requests","operationId":"research_requests_api_v1_admin_agent_moments_requests_get","parameters":[{"name":"x-moments-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Moments-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/agent/moments/stats":{"get":{"tags":["Admin - Moment Bank"],"summary":"Moment Stats","operationId":"moment_stats_api_v1_admin_agent_moments_stats_get","parameters":[{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/webhooks/revenuecat":{"post":{"tags":["Webhooks","Webhooks"],"summary":"Revenuecat Webhook","description":"Handle RevenueCat webhook events.\n\nEvents handled:\n- INITIAL_PURCHASE: New subscription created\n- RENEWAL: Subscription renewed, reset scan counter\n- CANCELLATION: User cancelled, access continues until period end\n- EXPIRATION: Subscription expired, revoke access\n- BILLING_ISSUE: Payment failed, grace period started\n- UNCANCELLATION: Cancellation reversed\n- PRODUCT_CHANGE: Plan/product changed\n\nSee: https://www.revenuecat.com/docs/integrations/webhooks","operationId":"revenuecat_webhook_api_v1_webhooks_revenuecat_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/webhooks/health":{"get":{"tags":["Webhooks","Webhooks"],"summary":"Webhook Health","description":"Health check endpoint for webhook service.\n\nUse this to verify webhook endpoints are accessible.\n\nReturns:\n    200 OK with service status","operationId":"webhook_health_api_v1_webhooks_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/webhooks/dealer-inventory":{"post":{"tags":["Webhooks","Webhooks"],"summary":"Dealer Inventory Webhook","description":"Webhook called by dealer-tools when inventory items are created/updated.\n\nSyncs dealer pricing data into price_observations and gemstonedb.","operationId":"dealer_inventory_webhook_api_v1_webhooks_dealer_inventory_post","parameters":[{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/webhooks/backfill-gemstonedb":{"post":{"tags":["Webhooks","Webhooks"],"summary":"Backfill Gemstonedb","description":"One-time backfill: push all completed scans into gemstonedb.","operationId":"backfill_gemstonedb_api_v1_webhooks_backfill_gemstonedb_post","parameters":[{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ratings/eligibility":{"get":{"tags":["Ratings","Ratings"],"summary":"Check Rating Eligibility","description":"Check if user is eligible for rating bonus\n\nReturns eligibility status and details:\n- can_rate: Whether user can submit a rating\n- is_bonus_applicable: Whether user will receive bonus scans\n- bonus_scans: Number of bonus scans (0 or 5)\n- message: User-friendly message\n\n**Scenarios:**\n- Free user, all scans used: can_rate=true, is_bonus_applicable=true, bonus_scans=5\n- Free user, scans remaining: can_rate=true, is_bonus_applicable=false, bonus_scans=0\n- Premium user: can_rate=true, is_bonus_applicable=false, bonus_scans=0\n- Already rated: can_rate=false, is_bonus_applicable=false, bonus_scans=0","operationId":"check_rating_eligibility_api_v1_ratings_eligibility_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RatingEligibilityResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/ratings/submit":{"post":{"tags":["Ratings","Ratings"],"summary":"Submit Rating","description":"Submit app rating and receive bonus scans if eligible\n\n**Requirements:**\n- User must not have rated before\n- Rating must be 1-5 stars\n- Comment is optional\n\n**Bonus scans:**\n- Free plan users who've used all scans: Receive 5 bonus scans\n- Premium users: Can rate for feedback, no bonus\n- Free users with scans remaining: Can rate, no bonus until scans used\n\n**Returns:**\n- success: true\n- rating_id: ID of created rating\n- bonus_scans_granted: Number of bonus scans (0 or 5)\n- new_scans_available: Updated scan count","operationId":"submit_rating_api_v1_ratings_submit_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubmitRatingRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubmitRatingResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/taxonomy":{"get":{"tags":["Taxonomy"],"summary":"Get Taxonomy","description":"Return the full taxonomy (public, useful for app-side validation too).","operationId":"get_taxonomy_api_v1_taxonomy_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/taxonomy/reload":{"post":{"tags":["Taxonomy"],"summary":"Reload Taxonomy","description":"Force reload taxonomy from DB. Admin-only (X-Admin-Key).\n\nGET /taxonomy stays public — the app reads it for client-side validation.","operationId":"reload_taxonomy_api_v1_taxonomy_reload_post","parameters":[{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/species/{species}/content":{"get":{"tags":["Species Content","Species Content"],"summary":"Get Species Content","description":"Public, cached. Returns 404 until content is populated for this species.","operationId":"get_species_content_api_v1_species__species__content_get","parameters":[{"name":"species","in":"path","required":true,"schema":{"type":"string","title":"Species"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SpeciesContentResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["Species Content","Species Content"],"summary":"Upsert Species Content","description":"Admin-only upsert. Bumps content_version on update. Pass `X-Admin-Actor`\nheader to record who edited (free-form, e.g. an ops username or script tag).","operationId":"upsert_species_content_api_v1_species__species__content_put","parameters":[{"name":"species","in":"path","required":true,"schema":{"type":"string","title":"Species"}},{"name":"X-Admin-Actor","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Actor"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SpeciesContentUpsert"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SpeciesContentResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/pieces/{jewelry_type}/content":{"get":{"tags":["Piece Content","Piece Content"],"summary":"Get Piece Type Content","operationId":"get_piece_type_content_api_v1_pieces__jewelry_type__content_get","parameters":[{"name":"jewelry_type","in":"path","required":true,"schema":{"type":"string","title":"Jewelry Type"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PieceTypeContentResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gems/dealer-scan":{"post":{"tags":["Dealer Scan"],"summary":"Dealer Scan","description":"Enhanced dealer scan with Gemini pre-analysis, GPT-4o, inline deep scan,\nand V2 market pricing. Streams progress via SSE.","operationId":"dealer_scan_api_v1_gems_dealer_scan_post","requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_dealer_scan_api_v1_gems_dealer_scan_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gems/tray-scan":{"post":{"tags":["Tray Scan"],"summary":"Tray Scan","description":"Accept ONE tray photograph, segment individual stones, and stream per-stone\nidentification results via SSE.\n\nResponse stream events:\n  - `start`    : {\"image_width\", \"image_height\"}\n  - `detected` : {\"stones\": [{\"index\",\"x\",\"y\",\"width\",\"height\",\"confidence\"}]}\n  - `stone`    : {\"index\",\"result\":{\"species\",..., \"market_insights\":...}}\n  - `error`    : {\"index\",\"message\"}\n  - `complete` : {\"total_detected\",\"total_identified\",\"elapsed_ms\"}","operationId":"tray_scan_api_v1_gems_tray_scan_post","requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_tray_scan_api_v1_gems_tray_scan_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/gems/{gem_id}/lab-request":{"post":{"tags":["Lab Certification"],"summary":"Create Lab Request","description":"Capture a lab-cert / origin-report request for the caller's own gem,\nstore the intent, then notify ops by email so the request gets actioned.","operationId":"create_lab_request_api_v1_gems__gem_id__lab_request_post","parameters":[{"name":"gem_id","in":"path","required":true,"schema":{"type":"integer","title":"Gem Id"}},{"name":"X-Device-Id","in":"header","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"X-Device-Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LabRequestCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LabRequestResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["Lab Certification"],"summary":"Get Lab Request","description":"Latest lab-cert request for the caller's own gem (status polling). Null if none.","operationId":"get_lab_request_api_v1_gems__gem_id__lab_request_get","parameters":[{"name":"gem_id","in":"path","required":true,"schema":{"type":"integer","title":"Gem Id"}},{"name":"X-Device-Id","in":"header","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"X-Device-Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/LabRequestResponse"},{"type":"null"}],"title":"Response Get Lab Request Api V1 Gems  Gem Id  Lab Request Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/email/unsubscribe":{"get":{"tags":["Email Preferences"],"summary":"Unsubscribe","description":"Opt a user out of consumer email via a signed link. Idempotent —\nre-opening the link is a no-op success.","operationId":"unsubscribe_api_v1_email_unsubscribe_get","parameters":[{"name":"token","in":"query","required":true,"schema":{"type":"string","description":"Signed unsubscribe token from the email footer","title":"Token"},"description":"Signed unsubscribe token from the email footer"}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["Email Preferences"],"summary":"Unsubscribe One Click","description":"RFC 8058 one-click unsubscribe target.\n\nMail clients that render a native \"Unsubscribe\" control POST here (no body\nis read, per the spec) when the message carries `List-Unsubscribe-Post`.\nThey expect a fast 2xx and show their own confirmation, so this returns a\nbare 200 rather than a page.","operationId":"unsubscribe_one_click_api_v1_email_unsubscribe_post","parameters":[{"name":"token","in":"query","required":true,"schema":{"type":"string","description":"Signed unsubscribe token from the email footer","title":"Token"},"description":"Signed unsubscribe token from the email footer"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/email/resubscribe":{"get":{"tags":["Email Preferences"],"summary":"Resubscribe","description":"Undo an opt-out. Reuses the unsubscribe token so the link on the\nconfirmation page works without an app login.","operationId":"resubscribe_api_v1_email_resubscribe_get","parameters":[{"name":"token","in":"query","required":true,"schema":{"type":"string","description":"Signed unsubscribe token (same token, reversed action)","title":"Token"},"description":"Signed unsubscribe token (same token, reversed action)"}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/lab-cert/mine":{"get":{"tags":["Lab Certification"],"summary":"List My Lab Requests","description":"All lab-cert requests made by the authenticated user, newest first, so the\napp can show each request's live status.","operationId":"list_my_lab_requests_api_v1_lab_cert_mine_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/LabRequestResponse"},"type":"array","title":"Response List My Lab Requests Api V1 Lab Cert Mine Get"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/lab-cert/{request_id}/status":{"patch":{"tags":["Lab Certification"],"summary":"Update Lab Request Status","description":"Admin: advance a lab-cert request's status. On the transition into\n`completed`, push + email the requesting user that their certification is\nready. Admin-gated via X-Admin-Key (same as other /admin endpoints).","operationId":"update_lab_request_status_api_v1_lab_cert__request_id__status_patch","parameters":[{"name":"request_id","in":"path","required":true,"schema":{"type":"integer","title":"Request Id"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LabStatusUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LabRequestResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/pricing/estimate":{"get":{"tags":["Pricing"],"summary":"Get Estimate","description":"Get a price estimate for a gemstone based on its characteristics.","operationId":"get_estimate_api_v1_pricing_estimate_get","parameters":[{"name":"type","in":"query","required":true,"schema":{"type":"string","description":"Gemstone type (e.g. Ruby, Sapphire)","title":"Type"},"description":"Gemstone type (e.g. Ruby, Sapphire)"},{"name":"carat","in":"query","required":false,"schema":{"type":"number","exclusiveMinimum":0.0,"default":1.0,"title":"Carat"}},{"name":"color","in":"query","required":false,"schema":{"type":"string","default":"","title":"Color"}},{"name":"clarity","in":"query","required":false,"schema":{"type":"string","default":"","title":"Clarity"}},{"name":"shape","in":"query","required":false,"schema":{"type":"string","default":"","title":"Shape"}},{"name":"cut","in":"query","required":false,"schema":{"type":"string","default":"","title":"Cut"}},{"name":"origin","in":"query","required":false,"schema":{"type":"string","default":"","title":"Origin"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EstimateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/pricing/v2/estimate":{"get":{"tags":["Pricing"],"summary":"Get V2 Estimate","description":"V2 pricing: comp-based with quality multiplier fallback.","operationId":"get_v2_estimate_api_v1_pricing_v2_estimate_get","parameters":[{"name":"species","in":"query","required":true,"schema":{"type":"string","description":"Gem species (e.g. Ruby, Sapphire, Emerald)","title":"Species"},"description":"Gem species (e.g. Ruby, Sapphire, Emerald)"},{"name":"carat","in":"query","required":false,"schema":{"type":"number","exclusiveMinimum":0.0,"default":1.0,"title":"Carat"}},{"name":"color","in":"query","required":false,"schema":{"type":"string","default":"","title":"Color"}},{"name":"clarity","in":"query","required":false,"schema":{"type":"string","default":"","title":"Clarity"}},{"name":"cut","in":"query","required":false,"schema":{"type":"string","default":"","title":"Cut"}},{"name":"origin","in":"query","required":false,"schema":{"type":"string","default":"","title":"Origin"}},{"name":"treatment","in":"query","required":false,"schema":{"type":"string","default":"","title":"Treatment"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/pricing/matrices/{gemstone_type}":{"get":{"tags":["Pricing"],"summary":"Get Price Matrix","description":"Get the color x weight price matrix for a gemstone type.","operationId":"get_price_matrix_api_v1_pricing_matrices__gemstone_type__get","parameters":[{"name":"gemstone_type","in":"path","required":true,"schema":{"type":"string","title":"Gemstone Type"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MatrixResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/pricing/history/{gemstone_type}":{"get":{"tags":["Pricing"],"summary":"Get Price History","description":"Get historical price data for a gemstone type.","operationId":"get_price_history_api_v1_pricing_history__gemstone_type__get","parameters":[{"name":"gemstone_type","in":"path","required":true,"schema":{"type":"string","title":"Gemstone Type"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HistoryResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/pricing/v2/comps":{"get":{"tags":["Pricing - Comps"],"summary":"List Comps","description":"Return individual comp listings with images, sorted by recency.\n\nRequires `image_url IS NOT NULL` — rows without a thumbnail are filtered out.\nEach axis filter is canonical-OR-legacy (see module docstring).","operationId":"list_comps_api_v1_pricing_v2_comps_get","parameters":[{"name":"species","in":"query","required":true,"schema":{"type":"string","description":"Gem species (e.g. Emerald, Ruby)","title":"Species"},"description":"Gem species (e.g. Emerald, Ruby)"},{"name":"carat","in":"query","required":false,"schema":{"anyOf":[{"type":"number","exclusiveMinimum":0.0},{"type":"null"}],"title":"Carat"}},{"name":"carat_window","in":"query","required":false,"schema":{"type":"number","maximum":1.0,"minimum":0.0,"description":"±fraction around carat","default":0.5,"title":"Carat Window"},"description":"±fraction around carat"},{"name":"color","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Canonical or free-text color","title":"Color"},"description":"Canonical or free-text color"},{"name":"color_grade","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Canonical color grade","title":"Color Grade"},"description":"Canonical color grade"},{"name":"clarity","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Clarity"}},{"name":"cut","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cut"}},{"name":"origin","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Origin"}},{"name":"treatment","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Treatment"}},{"name":"category","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"loose | ring | necklace | pendant | earring | bracelet | brooch","title":"Category"},"description":"loose | ring | necklace | pendant | earring | bracelet | brooch"},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":20,"minimum":1,"default":5,"title":"Page Size"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompListingsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/pricing/v2/ladder":{"get":{"tags":["Pricing - Ladder"],"summary":"Get Pricing Ladder","description":"Price/ct p25/p50/p75 by size band. Bands with n_comps < 5 are omitted;\n`ladder` is [] when the species has no usable comps (clients hide the section).","operationId":"get_pricing_ladder_api_v1_pricing_v2_ladder_get","parameters":[{"name":"species","in":"query","required":true,"schema":{"type":"string","minLength":1,"description":"Gem species (e.g. Sapphire, Ruby)","title":"Species"},"description":"Gem species (e.g. Sapphire, Ruby)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LadderResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/pricing/sales/ingest":{"post":{"tags":["Pricing - Sales Ingest"],"summary":"Ingest Sales","description":"Batch-ingest closed-sale records from dealer-tools (or any trusted\ntransaction source). Idempotent on (source_site, source_url).","operationId":"ingest_sales_api_v1_pricing_sales_ingest_post","parameters":[{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SalesIngestRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SalesIngestResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/market/index":{"get":{"tags":["Price Index"],"summary":"Get Index","description":"Get current GemstoneAI Price Index for all varieties.","operationId":"get_index_api_v1_market_index_get","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Page Size"}},{"name":"sort_by","in":"query","required":false,"schema":{"type":"string","default":"variety_asc","title":"Sort By"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IndexListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/market/index/top-movers":{"get":{"tags":["Price Index"],"summary":"Get Top Movers","description":"Get top gainers and losers across all varieties.","operationId":"get_top_movers_api_v1_market_index_top_movers_get","parameters":[{"name":"period","in":"query","required":false,"schema":{"type":"string","pattern":"^(1d|7d|30d)$","default":"7d","title":"Period"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":20,"minimum":1,"default":5,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TopMoversResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/market/index/{variety}/history":{"get":{"tags":["Price Index"],"summary":"Get Index History","description":"Get daily index history for a variety.","operationId":"get_index_history_api_v1_market_index__variety__history_get","parameters":[{"name":"variety","in":"path","required":true,"schema":{"type":"string","title":"Variety"}},{"name":"period","in":"query","required":false,"schema":{"type":"string","pattern":"^(7d|30d|90d|1y)$","default":"30d","title":"Period"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IndexHistoryResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/market/index/{variety}/movers":{"get":{"tags":["Price Index"],"summary":"Get Index Movers","description":"Get price movement explanations for a variety.","operationId":"get_index_movers_api_v1_market_index__variety__movers_get","parameters":[{"name":"variety","in":"path","required":true,"schema":{"type":"string","title":"Variety"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IndexMoversResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/market/admin/index/observation":{"post":{"tags":["Price Index"],"summary":"Add Observation","description":"Admin: manually add a price observation (auction result, dealer quote).","operationId":"add_observation_api_v1_market_admin_index_observation_post","parameters":[{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminObservationRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/market/admin/index/recompute":{"post":{"tags":["Price Index"],"summary":"Recompute Index","description":"Admin: force recomputation of today's index.","operationId":"recompute_index_api_v1_market_admin_index_recompute_post","parameters":[{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/market/admin/index/bootstrap":{"post":{"tags":["Price Index"],"summary":"Bootstrap","description":"Admin: bootstrap index from GemstoneMarketData.","operationId":"bootstrap_api_v1_market_admin_index_bootstrap_post","parameters":[{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/market/admin/index/supply-graph/seed":{"post":{"tags":["Price Index"],"summary":"Seed Graph","description":"Admin: seed or update supply knowledge graph from JSON.","operationId":"seed_graph_api_v1_market_admin_index_supply_graph_seed_post","parameters":[{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/market/admin/index/news/scrape":{"post":{"tags":["Price Index"],"summary":"Trigger News Scrape","description":"Admin: manually trigger news scrape pipeline.","operationId":"trigger_news_scrape_api_v1_market_admin_index_news_scrape_post","parameters":[{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/market/admin/index/news/generate-notes":{"post":{"tags":["Price Index"],"summary":"Trigger Market Notes","description":"Admin: manually trigger GemstoneAI market note generation (LNK-MKT2).","operationId":"trigger_market_notes_api_v1_market_admin_index_news_generate_notes_post","parameters":[{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/market/admin/index/news/retag":{"post":{"tags":["Price Index"],"summary":"Retag News Species","description":"Admin: backfill affected_species on recent untagged articles using the\ndeterministic variety-name matcher. One-shot after deploying the matcher —\nnew articles are tagged at ingest.","operationId":"retag_news_species_api_v1_market_admin_index_news_retag_post","parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","default":30,"title":"Days"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/market/admin/index/gold-brief/run":{"post":{"tags":["Price Index"],"summary":"Run Gold Brief Admin","description":"Admin: generate today's Gold Morning Brief. push=false (default)\ngenerates the STORY only — safe to test any time. push=true runs the full\njob including the North America push (threshold-gated) — real sends.","operationId":"run_gold_brief_admin_api_v1_market_admin_index_gold_brief_run_post","parameters":[{"name":"push","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Push"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/market/admin/index/news/breaking-push/run":{"post":{"tags":["Price Index"],"summary":"Run Breaking Push Admin","description":"Admin: run the breaking-news push check (LNK-BREAKING). dry_run=true\n(default) reports the qualifying event, exact push copy, and audience\ncount without sending. dry_run=false sends for real to EVERY token\nholder — BREAKING_PUSH_LIVE only gates the cron, not this endpoint.","operationId":"run_breaking_push_admin_api_v1_market_admin_index_news_breaking_push_run_post","parameters":[{"name":"dry_run","in":"query","required":false,"schema":{"type":"boolean","default":true,"title":"Dry Run"}},{"name":"lookback_hours","in":"query","required":false,"schema":{"type":"integer","default":48,"title":"Lookback Hours"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/market/admin/index/news/stats":{"get":{"tags":["Price Index"],"summary":"News Stats","description":"Admin: news pipeline stats, incl. per-source and per-variety skew\nover the last `days` — the observability that was missing when Tier 2\nRSS silently contributed zero items (LNK-MKT2).","operationId":"news_stats_api_v1_market_admin_index_news_stats_get","parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","default":14,"title":"Days"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/market/news":{"get":{"tags":["Market News"],"summary":"Get Market News","description":"Paginated market news feed, optionally filtered by variety or category.\n\ninclude_family=true (additive, LNK-MKT2 contract): when variety-tagged\nresults fill less than page_size, family-level items (corundum, beryl,\ngarnet group…) are appended with is_family_level=true. Default behavior\nis unchanged. GemstoneAI analysis notes are excluded from the unfiltered\nfeed; they surface in variety feeds or via category=gemstoneai_note.","operationId":"get_market_news_api_v1_market_news_get","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":20,"title":"Page Size"}},{"name":"variety","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Variety"}},{"name":"category","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category"}},{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":365,"minimum":1,"default":30,"title":"Days"}},{"name":"include_family","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Include Family"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NewsFeedResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/market/news/feed":{"get":{"tags":["Market News"],"summary":"Get Curated Feed","description":"Curated feed: latest 10 news events + most recent weekly report.","operationId":"get_curated_feed_api_v1_market_news_feed_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketReportResponse"}}}}}}},"/api/v1/market/events":{"get":{"tags":["Market News"],"summary":"Get Active Events","description":"Active market events — persistent, duration-aware. The source of truth for price signals.","operationId":"get_active_events_api_v1_market_events_get","parameters":[{"name":"variety","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Variety"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/market/news/{news_id}":{"get":{"tags":["Market News"],"summary":"Get News Detail","description":"Single news event detail.","operationId":"get_news_detail_api_v1_market_news__news_id__get","parameters":[{"name":"news_id","in":"path","required":true,"schema":{"type":"integer","title":"News Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NewsEventDetail"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/market/{variety}/news":{"get":{"tags":["Market News"],"summary":"Get Variety News","description":"News affecting a specific gem variety. Falls back to gem-family news\n(sibling varieties, e.g. Sapphire→Corundum→Ruby) when no variety-specific\nitems exist; family_fallback=true marks that case (LNK-MKT2).","operationId":"get_variety_news_api_v1_market__variety__news_get","parameters":[{"name":"variety","in":"path","required":true,"schema":{"type":"string","title":"Variety"}},{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":365,"minimum":1,"default":30,"title":"Days"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":10,"title":"Page Size"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NewsFeedResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/market/articles":{"get":{"tags":["Market News"],"summary":"Get Market Articles","description":"GemstoneAI-authored market intelligence articles.","operationId":"get_market_articles_api_v1_market_articles_get","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":10,"title":"Page Size"}},{"name":"tag","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tag"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/market/articles/{article_id}":{"get":{"tags":["Market News"],"summary":"Get Market Article","description":"Full article content with rich structured fields.","operationId":"get_market_article_api_v1_market_articles__article_id__get","parameters":[{"name":"article_id","in":"path","required":true,"schema":{"type":"string","title":"Article Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gtm/prospects":{"get":{"tags":["GTM - Prospects"],"summary":"List Prospects","description":"List prospects with filters + pagination.","operationId":"list_prospects_api_v1_gtm_prospects_get","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":50,"title":"Page Size"}},{"name":"business_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Business Type"}},{"name":"relationship_stage","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Relationship Stage"}},{"name":"agta_member","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Agta Member"}},{"name":"jck_exhibitor","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Jck Exhibitor"}},{"name":"suppressed","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Suppressed"}},{"name":"stone_focus","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Stone Focus"}},{"name":"search","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Search"}},{"name":"sort","in":"query","required":false,"schema":{"type":"string","default":"updated_at_desc","title":"Sort"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProspectListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["GTM - Prospects"],"summary":"Create Prospect","operationId":"create_prospect_api_v1_gtm_prospects_post","parameters":[{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProspectCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProspectResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gtm/prospects/stats":{"get":{"tags":["GTM - Prospects"],"summary":"Prospect Stats","description":"Aggregate stats for GTM admin dashboard.","operationId":"prospect_stats_api_v1_gtm_prospects_stats_get","parameters":[{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProspectStats"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gtm/prospects/{prospect_id}":{"get":{"tags":["GTM - Prospects"],"summary":"Get Prospect","operationId":"get_prospect_api_v1_gtm_prospects__prospect_id__get","parameters":[{"name":"prospect_id","in":"path","required":true,"schema":{"type":"integer","title":"Prospect Id"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProspectResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["GTM - Prospects"],"summary":"Update Prospect","operationId":"update_prospect_api_v1_gtm_prospects__prospect_id__patch","parameters":[{"name":"prospect_id","in":"path","required":true,"schema":{"type":"integer","title":"Prospect Id"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProspectUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProspectResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["GTM - Prospects"],"summary":"Delete Prospect","operationId":"delete_prospect_api_v1_gtm_prospects__prospect_id__delete","parameters":[{"name":"prospect_id","in":"path","required":true,"schema":{"type":"integer","title":"Prospect Id"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gtm/prospects/import":{"post":{"tags":["GTM - Prospects"],"summary":"Import Prospects Csv","description":"Import prospects from CSV.\n\nExpected columns: company_name (required) + any of the optional columns.\nDedup on primary_contact_email (if present), else on (company_name + website_domain).","operationId":"import_prospects_csv_api_v1_gtm_prospects_import_post","parameters":[{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_import_prospects_csv_api_v1_gtm_prospects_import_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProspectImportResult"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gtm/prospects/{prospect_id}/signals":{"get":{"tags":["GTM - Prospects"],"summary":"List Signals","operationId":"list_signals_api_v1_gtm_prospects__prospect_id__signals_get","parameters":[{"name":"prospect_id","in":"path","required":true,"schema":{"type":"integer","title":"Prospect Id"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ProspectSignalResponse"},"title":"Response List Signals Api V1 Gtm Prospects  Prospect Id  Signals Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["GTM - Prospects"],"summary":"Add Signal","operationId":"add_signal_api_v1_gtm_prospects__prospect_id__signals_post","parameters":[{"name":"prospect_id","in":"path","required":true,"schema":{"type":"integer","title":"Prospect Id"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProspectSignalCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProspectSignalResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gtm/prospects/{prospect_id}/enrich":{"post":{"tags":["GTM - Prospects"],"summary":"Trigger Enrichment","description":"Queue enrichment job. Returns 202 immediately; worker processes async.","operationId":"trigger_enrichment_api_v1_gtm_prospects__prospect_id__enrich_post","parameters":[{"name":"prospect_id","in":"path","required":true,"schema":{"type":"integer","title":"Prospect Id"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProspectEnrichRequest"}}}},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gtm/content/queue":{"get":{"tags":["GTM - Content"],"summary":"List Queue","operationId":"list_queue_api_v1_gtm_content_queue_get","parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},{"name":"insight_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Insight Type"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Page Size"}},{"name":"include_expired","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Include Expired"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContentQueueListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gtm/content/queue/{item_id}":{"get":{"tags":["GTM - Content"],"summary":"Get Queue Item","operationId":"get_queue_item_api_v1_gtm_content_queue__item_id__get","parameters":[{"name":"item_id","in":"path","required":true,"schema":{"type":"integer","title":"Item Id"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContentQueueItemResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gtm/content/queue/{item_id}/expire":{"post":{"tags":["GTM - Content"],"summary":"Expire Queue Item","operationId":"expire_queue_item_api_v1_gtm_content_queue__item_id__expire_post","parameters":[{"name":"item_id","in":"path","required":true,"schema":{"type":"integer","title":"Item Id"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gtm/content/hero":{"get":{"tags":["GTM - Content"],"summary":"List Hero Pieces","operationId":"list_hero_pieces_api_v1_gtm_content_hero_get","parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},{"name":"mode","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mode"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/HeroPieceResponse"},"title":"Response List Hero Pieces Api V1 Gtm Content Hero Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gtm/content/hero/{hero_id}":{"get":{"tags":["GTM - Content"],"summary":"Get Hero Piece","operationId":"get_hero_piece_api_v1_gtm_content_hero__hero_id__get","parameters":[{"name":"hero_id","in":"path","required":true,"schema":{"type":"integer","title":"Hero Id"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HeroPieceResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gtm/content/hero/generate":{"post":{"tags":["GTM - Content"],"summary":"Generate Hero","description":"Queue hero piece generation. Returns job info.","operationId":"generate_hero_api_v1_gtm_content_hero_generate_post","parameters":[{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HeroPieceGenerateRequest"}}}},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gtm/content/hero/{hero_id}/approve":{"post":{"tags":["GTM - Content"],"summary":"Approve Hero","operationId":"approve_hero_api_v1_gtm_content_hero__hero_id__approve_post","parameters":[{"name":"hero_id","in":"path","required":true,"schema":{"type":"integer","title":"Hero Id"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HeroPieceApproveRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HeroPieceResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gtm/content/hero/{hero_id}/atomize":{"post":{"tags":["GTM - Content"],"summary":"Atomize Hero","description":"Trigger atomization: hero piece → N platform outputs.","operationId":"atomize_hero_api_v1_gtm_content_hero__hero_id__atomize_post","parameters":[{"name":"hero_id","in":"path","required":true,"schema":{"type":"integer","title":"Hero Id"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"requestBody":{"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/AtomizeRequest"},{"type":"null"}],"title":"Data"}}}},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gtm/content/outputs":{"get":{"tags":["GTM - Content"],"summary":"List Outputs","operationId":"list_outputs_api_v1_gtm_content_outputs_get","parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},{"name":"platform","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Platform"}},{"name":"hero_piece_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Hero Piece Id"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Page Size"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContentOutputListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gtm/content/outputs/{output_id}/review":{"post":{"tags":["GTM - Content"],"summary":"Review Output","operationId":"review_output_api_v1_gtm_content_outputs__output_id__review_post","parameters":[{"name":"output_id","in":"path","required":true,"schema":{"type":"integer","title":"Output Id"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContentOutputReviewRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContentOutputResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gtm/content/outputs/bulk-approve":{"post":{"tags":["GTM - Content"],"summary":"Bulk Approve","description":"Approve many outputs at once (low-stakes variants).","operationId":"bulk_approve_api_v1_gtm_content_outputs_bulk_approve_post","parameters":[{"name":"reviewed_by","in":"query","required":true,"schema":{"type":"string","title":"Reviewed By"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"array","items":{"type":"integer"},"title":"Output Ids"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gtm/content/schedule":{"get":{"tags":["GTM - Content"],"summary":"List Schedule","operationId":"list_schedule_api_v1_gtm_content_schedule_get","parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},{"name":"platform","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Platform"}},{"name":"from_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"From Date"}},{"name":"to_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"To Date"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":200,"title":"Limit"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ContentScheduleResponse"},"title":"Response List Schedule Api V1 Gtm Content Schedule Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["GTM - Content"],"summary":"Create Schedule","operationId":"create_schedule_api_v1_gtm_content_schedule_post","parameters":[{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScheduleRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContentScheduleResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gtm/content/schedule/{schedule_id}":{"delete":{"tags":["GTM - Content"],"summary":"Cancel Schedule","operationId":"cancel_schedule_api_v1_gtm_content_schedule__schedule_id__delete","parameters":[{"name":"schedule_id","in":"path","required":true,"schema":{"type":"integer","title":"Schedule Id"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gtm/outbound/sequences":{"get":{"tags":["GTM - Outbound"],"summary":"List Sequences","operationId":"list_sequences_api_v1_gtm_outbound_sequences_get","parameters":[{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/EmailSequenceResponse"},"title":"Response List Sequences Api V1 Gtm Outbound Sequences Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["GTM - Outbound"],"summary":"Create Sequence","operationId":"create_sequence_api_v1_gtm_outbound_sequences_post","parameters":[{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailSequenceCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailSequenceResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gtm/outbound/sequences/{sequence_id}":{"get":{"tags":["GTM - Outbound"],"summary":"Get Sequence","operationId":"get_sequence_api_v1_gtm_outbound_sequences__sequence_id__get","parameters":[{"name":"sequence_id","in":"path","required":true,"schema":{"type":"integer","title":"Sequence Id"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailSequenceResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["GTM - Outbound"],"summary":"Update Sequence","operationId":"update_sequence_api_v1_gtm_outbound_sequences__sequence_id__patch","parameters":[{"name":"sequence_id","in":"path","required":true,"schema":{"type":"integer","title":"Sequence Id"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailSequenceUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailSequenceResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gtm/outbound/campaigns":{"get":{"tags":["GTM - Outbound"],"summary":"List Campaigns","operationId":"list_campaigns_api_v1_gtm_outbound_campaigns_get","parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},{"name":"sequence_name","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sequence Name"}},{"name":"prospect_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Prospect Id"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":50,"title":"Page Size"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailCampaignListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["GTM - Outbound"],"summary":"Enroll Campaign","operationId":"enroll_campaign_api_v1_gtm_outbound_campaigns_post","parameters":[{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailCampaignCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailCampaignResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gtm/outbound/campaigns/bulk-enroll":{"post":{"tags":["GTM - Outbound"],"summary":"Bulk Enroll","operationId":"bulk_enroll_api_v1_gtm_outbound_campaigns_bulk_enroll_post","parameters":[{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkEnrollRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkEnrollResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gtm/outbound/campaigns/{campaign_id}/pause":{"post":{"tags":["GTM - Outbound"],"summary":"Pause Campaign","operationId":"pause_campaign_api_v1_gtm_outbound_campaigns__campaign_id__pause_post","parameters":[{"name":"campaign_id","in":"path","required":true,"schema":{"type":"integer","title":"Campaign Id"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailCampaignResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gtm/outbound/campaigns/{campaign_id}/resume":{"post":{"tags":["GTM - Outbound"],"summary":"Resume Campaign","operationId":"resume_campaign_api_v1_gtm_outbound_campaigns__campaign_id__resume_post","parameters":[{"name":"campaign_id","in":"path","required":true,"schema":{"type":"integer","title":"Campaign Id"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailCampaignResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gtm/outbound/sends":{"get":{"tags":["GTM - Outbound"],"summary":"List Sends","operationId":"list_sends_api_v1_gtm_outbound_sends_get","parameters":[{"name":"campaign_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Campaign Id"}},{"name":"review_state","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Review State"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":100,"title":"Limit"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/EmailSendResponse"},"title":"Response List Sends Api V1 Gtm Outbound Sends Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gtm/outbound/sends/{send_id}/review":{"post":{"tags":["GTM - Outbound"],"summary":"Review Send","operationId":"review_send_api_v1_gtm_outbound_sends__send_id__review_post","parameters":[{"name":"send_id","in":"path","required":true,"schema":{"type":"integer","title":"Send Id"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailSendReviewRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailSendResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gtm/outbound/suppression":{"get":{"tags":["GTM - Outbound"],"summary":"List Suppression","operationId":"list_suppression_api_v1_gtm_outbound_suppression_get","parameters":[{"name":"reason","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":1000,"minimum":1,"default":200,"title":"Limit"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SuppressionResponse"},"title":"Response List Suppression Api V1 Gtm Outbound Suppression Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["GTM - Outbound"],"summary":"Add Suppression","operationId":"add_suppression_api_v1_gtm_outbound_suppression_post","parameters":[{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuppressionEntry"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuppressionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gtm/outbound/stats":{"get":{"tags":["GTM - Outbound"],"summary":"Outbound Stats","operationId":"outbound_stats_api_v1_gtm_outbound_stats_get","parameters":[{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OutboundStats"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gtm/charts/generate":{"post":{"tags":["GTM - Charts"],"summary":"Generate Chart","description":"Generate a branded chart and return its S3 URL.\n\nQuery spec shape varies by chart_type — see `app.charts.service._fetch_data` for details.\nCan bypass DB fetch entirely by including `inline_data` in query_spec.","operationId":"generate_chart_api_v1_gtm_charts_generate_post","parameters":[{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChartGenerateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChartGenerateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gtm/charts/types":{"get":{"tags":["GTM - Charts"],"summary":"List Chart Types","description":"Enumerate available chart types and aspect ratios.","operationId":"list_chart_types_api_v1_gtm_charts_types_get","parameters":[{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gtm/newsletter/subscribe":{"post":{"tags":["GTM - Newsletter"],"summary":"Subscribe","description":"Public signup endpoint. Writes to local DB AND Beehiiv.\n\nIdempotent — if email exists and was unsubscribed, reactivates. If active, returns existing.","operationId":"subscribe_api_v1_gtm_newsletter_subscribe_post","parameters":[{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriberSignupRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriberSignupResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gtm/newsletter/unsubscribe":{"post":{"tags":["GTM - Newsletter"],"summary":"Unsubscribe","operationId":"unsubscribe_api_v1_gtm_newsletter_unsubscribe_post","parameters":[{"name":"email","in":"query","required":true,"schema":{"type":"string","title":"Email"}},{"name":"reason","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gtm/newsletter/editions":{"get":{"tags":["GTM - Newsletter"],"summary":"List Editions","operationId":"list_editions_api_v1_gtm_newsletter_editions_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Limit"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NewsletterEditionListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gtm/newsletter/editions/{edition_id}":{"get":{"tags":["GTM - Newsletter"],"summary":"Get Edition","operationId":"get_edition_api_v1_gtm_newsletter_editions__edition_id__get","parameters":[{"name":"edition_id","in":"path","required":true,"schema":{"type":"integer","title":"Edition Id"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NewsletterEditionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gtm/newsletter/compose":{"post":{"tags":["GTM - Newsletter"],"summary":"Trigger Compose","description":"Trigger weekly compose. Runs via ARQ so endpoint returns fast.\n\nReturns job_id so admin can poll or subscribe to progress.","operationId":"trigger_compose_api_v1_gtm_newsletter_compose_post","parameters":[{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ComposeRequest"}}}},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gtm/newsletter/editions/{edition_id}/schedule":{"post":{"tags":["GTM - Newsletter"],"summary":"Schedule Edition","description":"Schedule a reviewed edition for send via Beehiiv.","operationId":"schedule_edition_api_v1_gtm_newsletter_editions__edition_id__schedule_post","parameters":[{"name":"edition_id","in":"path","required":true,"schema":{"type":"integer","title":"Edition Id"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScheduleEditionRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NewsletterEditionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gtm/newsletter/subscribers":{"get":{"tags":["GTM - Newsletter"],"summary":"List Subscribers","operationId":"list_subscribers_api_v1_gtm_newsletter_subscribers_get","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":50,"title":"Page Size"}},{"name":"lifecycle_stage","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lifecycle Stage"}},{"name":"source","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriberListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gtm/newsletter/stats":{"get":{"tags":["GTM - Newsletter"],"summary":"Newsletter Stats","operationId":"newsletter_stats_api_v1_gtm_newsletter_stats_get","parameters":[{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NewsletterStats"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gtm/demo/prep":{"post":{"tags":["GTM - Demo"],"summary":"Trigger Demo Prep","description":"Manually queue a demo prep run. Use from admin UI when Calendly webhook missed.","operationId":"trigger_demo_prep_api_v1_gtm_demo_prep_post","parameters":[{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DemoPrepRequest"}}}},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DemoPrepResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gtm/demo/briefs/{prospect_id}":{"get":{"tags":["GTM - Demo"],"summary":"Get Latest Brief","operationId":"get_latest_brief_api_v1_gtm_demo_briefs__prospect_id__get","parameters":[{"name":"prospect_id","in":"path","required":true,"schema":{"type":"integer","title":"Prospect Id"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DemoBriefResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gtm/demo/upcoming":{"get":{"tags":["GTM - Demo"],"summary":"List Upcoming Demos","description":"Prospects in a demo-related stage. Default is `demo_booked` (upcoming) — use\n`stage=demo_done` for past demos, or `stage=all` to include both + proposal_sent.\n\nThin version for MVP — admin UI shows these as a watchlist.","operationId":"list_upcoming_demos_api_v1_gtm_demo_upcoming_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":20,"title":"Limit"}},{"name":"stage","in":"query","required":false,"schema":{"type":"string","default":"demo_booked","title":"Stage"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gtm/demo/voice-note":{"post":{"tags":["GTM - Demo"],"summary":"Upload Voice Note","description":"Accept a voice note (iOS Shortcut / admin upload), stash on S3, enqueue process.","operationId":"upload_voice_note_api_v1_gtm_demo_voice_note_post","parameters":[{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_upload_voice_note_api_v1_gtm_demo_voice_note_post"}}}},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VoiceNoteUploadResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gtm/demo/followup/{prospect_id}":{"get":{"tags":["GTM - Demo"],"summary":"Get Followup Draft","operationId":"get_followup_draft_api_v1_gtm_demo_followup__prospect_id__get","parameters":[{"name":"prospect_id","in":"path","required":true,"schema":{"type":"integer","title":"Prospect Id"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FollowupDraftResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gtm/demo/followup/{prospect_id}/approve":{"post":{"tags":["GTM - Demo"],"summary":"Approve Followup","operationId":"approve_followup_api_v1_gtm_demo_followup__prospect_id__approve_post","parameters":[{"name":"prospect_id","in":"path","required":true,"schema":{"type":"integer","title":"Prospect Id"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FollowupApprovalRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gtm/onboarding":{"get":{"tags":["GTM - Onboarding"],"summary":"List Onboarding","operationId":"list_onboarding_api_v1_gtm_onboarding_get","parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"active | completed | all","title":"Status"},"description":"active | completed | all"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":100,"title":"Limit"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerOnboardingListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gtm/onboarding/stats":{"get":{"tags":["GTM - Onboarding"],"summary":"Onboarding Stats","operationId":"onboarding_stats_api_v1_gtm_onboarding_stats_get","parameters":[{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OnboardingStats"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gtm/onboarding/{dealer_customer_id}":{"get":{"tags":["GTM - Onboarding"],"summary":"Get Onboarding","operationId":"get_onboarding_api_v1_gtm_onboarding__dealer_customer_id__get","parameters":[{"name":"dealer_customer_id","in":"path","required":true,"schema":{"type":"string","title":"Dealer Customer Id"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerOnboardingResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gtm/onboarding/{dealer_customer_id}/touchpoints":{"get":{"tags":["GTM - Onboarding"],"summary":"List Touchpoints","operationId":"list_touchpoints_api_v1_gtm_onboarding__dealer_customer_id__touchpoints_get","parameters":[{"name":"dealer_customer_id","in":"path","required":true,"schema":{"type":"string","title":"Dealer Customer Id"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TouchpointResponse"},"title":"Response List Touchpoints Api V1 Gtm Onboarding  Dealer Customer Id  Touchpoints Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gtm/onboarding/bootstrap":{"post":{"tags":["GTM - Onboarding"],"summary":"Bootstrap","description":"Create onboarding + 8 touchpoints for a new customer. Idempotent.","operationId":"bootstrap_api_v1_gtm_onboarding_bootstrap_post","parameters":[{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BootstrapRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerOnboardingResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gtm/onboarding/milestones":{"post":{"tags":["GTM - Onboarding"],"summary":"Ingest Milestone","description":"Record a milestone hit (alternate to dealer-tools webhook).","operationId":"ingest_milestone_api_v1_gtm_onboarding_milestones_post","parameters":[{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MilestoneIngestRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gtm/onboarding/dispatch-now":{"post":{"tags":["GTM - Onboarding"],"summary":"Dispatch Now","description":"Manual trigger for the hourly dispatcher (admin shortcut; otherwise runs at :15 every hour).","operationId":"dispatch_now_api_v1_gtm_onboarding_dispatch_now_post","parameters":[{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gtm/onboarding/rescore-churn":{"post":{"tags":["GTM - Onboarding"],"summary":"Rescore Churn","description":"Manual trigger for the nightly churn rescore.","operationId":"rescore_churn_api_v1_gtm_onboarding_rescore_churn_post","parameters":[{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gtm/crm/sync/prospects/{prospect_id}":{"post":{"tags":["GTM - CRM"],"summary":"Trigger Sync Prospect","description":"Queue a single prospect → Attio sync.","operationId":"trigger_sync_prospect_api_v1_gtm_crm_sync_prospects__prospect_id__post","parameters":[{"name":"prospect_id","in":"path","required":true,"schema":{"type":"integer","title":"Prospect Id"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gtm/crm/sync/reconcile":{"post":{"tags":["GTM - CRM"],"summary":"Trigger Reconcile","description":"Run the daily reconciliation pass on-demand.","operationId":"trigger_reconcile_api_v1_gtm_crm_sync_reconcile_post","parameters":[{"name":"lookback_hours","in":"query","required":false,"schema":{"type":"integer","maximum":168,"minimum":1,"default":24,"title":"Lookback Hours"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gtm/crm/health":{"get":{"tags":["GTM - CRM"],"summary":"Crm Health","description":"Quick Attio connectivity check + config validation.","operationId":"crm_health_api_v1_gtm_crm_health_get","parameters":[{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gtm/consumers/":{"get":{"tags":["GTM - Consumers"],"summary":"List Consumers","operationId":"list_consumers_api_v1_gtm_consumers__get","parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"paid|free|churned|trialing","title":"Status"},"description":"paid|free|churned|trialing"},{"name":"search","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"email / name / mobile","title":"Search"},"description":"email / name / mobile"},{"name":"sort","in":"query","required":false,"schema":{"type":"string","description":"signup_desc|signup_asc|last_scan_desc|mrr_desc","default":"signup_desc","title":"Sort"},"description":"signup_desc|signup_asc|last_scan_desc|mrr_desc"},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Page Size"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConsumerListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gtm/consumers/stats":{"get":{"tags":["GTM - Consumers"],"summary":"Consumer Stats","operationId":"consumer_stats_api_v1_gtm_consumers_stats_get","parameters":[{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConsumerStats"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gtm/consumers/breakdown":{"get":{"tags":["GTM - Consumers"],"summary":"Consumer Breakdown","description":"Aggregate paying subscribers by store, billing period, and product_id.\n\n\"Paying\" = latest sub per user with status=active AND plan_option.price > 0.\nChurning = paying AND cancel_at_period_end.","operationId":"consumer_breakdown_api_v1_gtm_consumers_breakdown_get","parameters":[{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConsumerBreakdown"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gtm/consumers/activity":{"get":{"tags":["GTM - Consumers"],"summary":"Consumer Activity","description":"Recent subscription state changes.\n\nWe don't persist a subscription_events log, so we infer activity from\nUserSubscription.created_at + updated_at + cancelled_at +\ncancel_at_period_end + status transitions.","operationId":"consumer_activity_api_v1_gtm_consumers_activity_get","parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":365,"minimum":1,"default":30,"title":"Days"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":20,"title":"Limit"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConsumerActivityResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gtm/consumers/attribution":{"get":{"tags":["GTM - Consumers"],"summary":"Consumer Attribution","description":"Signups in the window grouped by first-touch install attribution.\n\nAttribution is write-once from the Android Play referrer or an attributed\ndeep link (LNK-ATTR); iOS store installs arrive unattributed, so iOS\nper-campaign counts come from App Store Connect campaign tokens instead.\nscanned = at least one own scan (outreach scans excluded). paid = latest\nsubscription paid or cancelled-but-active, from local status only.","operationId":"consumer_attribution_api_v1_gtm_consumers_attribution_get","parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":365,"minimum":1,"default":30,"title":"Days"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConsumerAttribution"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gtm/consumers/{user_id}":{"get":{"tags":["GTM - Consumers"],"summary":"Get Consumer","operationId":"get_consumer_api_v1_gtm_consumers__user_id__get","parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"integer","title":"User Id"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConsumerDetail"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gtm/consumers/{user_id}/rc-sync":{"post":{"tags":["GTM - Consumers"],"summary":"Sync Consumer From Rc","description":"Fetch live state from RevenueCat and update the local UserSubscription.\n\nResolves webhook lag when ops needs the current truth for a single user.","operationId":"sync_consumer_from_rc_api_v1_gtm_consumers__user_id__rc_sync_post","parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"integer","title":"User Id"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RcSyncResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/webhooks/gtm/instantly":{"post":{"tags":["GTM - Webhooks"],"summary":"Instantly Webhook","operationId":"instantly_webhook_api_v1_webhooks_gtm_instantly_post","parameters":[{"name":"x-instantly-signature","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Instantly-Signature"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/webhooks/gtm/attio":{"post":{"tags":["GTM - Webhooks"],"summary":"Attio Webhook","operationId":"attio_webhook_api_v1_webhooks_gtm_attio_post","parameters":[{"name":"x-attio-signature","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Attio-Signature"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/webhooks/gtm/calendly":{"post":{"tags":["GTM - Webhooks"],"summary":"Calendly Webhook","operationId":"calendly_webhook_api_v1_webhooks_gtm_calendly_post","parameters":[{"name":"Calendly-Webhook-Signature","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Calendly-Webhook-Signature"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/webhooks/gtm/beehiiv":{"post":{"tags":["GTM - Webhooks"],"summary":"Beehiiv Webhook","operationId":"beehiiv_webhook_api_v1_webhooks_gtm_beehiiv_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/webhooks/gtm/expandi":{"post":{"tags":["GTM - Webhooks"],"summary":"Expandi Webhook","operationId":"expandi_webhook_api_v1_webhooks_gtm_expandi_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/webhooks/gtm/dealer-tools/milestone":{"post":{"tags":["GTM - Webhooks"],"summary":"Dealer Tools Milestone Webhook","operationId":"dealer_tools_milestone_webhook_api_v1_webhooks_gtm_dealer_tools_milestone_post","parameters":[{"name":"x-dealer-tools-signature","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Dealer-Tools-Signature"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/":{"get":{"summary":"Root","operationId":"root__get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/health":{"get":{"summary":"Health","description":"Real liveness probe. [LNK-OPSHEALTH]\n\nThis used to return `{\"status\": \"healthy\", \"timestamp\": \"2024-11-10T12:00:00Z\"}`\n— a hardcoded string that checked nothing and could not fail. `deploy.sh`\ngates the deploy on it, so a deploy that broke the database still reported\nsuccess, and on 2026-08-15 a disk-full Postgres outage ran for three days\nwhile every surface above it looked healthy.\n\nContract:\n  * **503 when the database is unreachable** — this is what makes\n    `curl -fsS` in deploy.sh a real gate.\n  * **200 with a warning when disk is low.** A full disk is serious but\n    failing the deploy on it would block the very deploy that might fix it.","operationId":"health_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}}},"components":{"schemas":{"AdminCoverageIntentRow":{"properties":{"id":{"type":"integer","title":"Id"},"user_id":{"type":"integer","title":"User Id"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email"},"gemstone_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Gemstone Id"},"piece":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Piece"},"kind":{"type":"string","title":"Kind"},"item_value":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Item Value"},"status":{"type":"string","title":"Status"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","user_id","email","gemstone_id","piece","kind","item_value","status","created_at"],"title":"AdminCoverageIntentRow"},"AdminCoverageIntentsResponse":{"properties":{"summary":{"$ref":"#/components/schemas/AdminCoverageSummary"},"intents":{"items":{"$ref":"#/components/schemas/AdminCoverageIntentRow"},"type":"array","title":"Intents"},"provider_clicks":{"items":{"$ref":"#/components/schemas/AdminProviderClickRow"},"type":"array","title":"Provider Clicks"}},"type":"object","required":["summary","intents","provider_clicks"],"title":"AdminCoverageIntentsResponse"},"AdminCoverageSummary":{"properties":{"coverage_intents":{"type":"integer","title":"Coverage Intents"},"appraisal_intents":{"type":"integer","title":"Appraisal Intents"},"users_with_intent":{"type":"integer","title":"Users With Intent"},"items_flagged":{"type":"integer","title":"Items Flagged"},"value_flagged":{"type":"number","title":"Value Flagged"},"schedulable_items_catalogued":{"type":"integer","title":"Schedulable Items Catalogued"},"schedulable_items_flagged_pct":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Schedulable Items Flagged Pct"}},"type":"object","required":["coverage_intents","appraisal_intents","users_with_intent","items_flagged","value_flagged","schedulable_items_catalogued","schedulable_items_flagged_pct"],"title":"AdminCoverageSummary","description":"The adoption read-out: intent counts against what was catalogued."},"AdminLeadStatusUpdate":{"properties":{"status":{"type":"string","title":"Status"}},"type":"object","required":["status"],"title":"AdminLeadStatusUpdate"},"AdminObservationRequest":{"properties":{"gemstone_type":{"type":"string","title":"Gemstone Type"},"price_usd":{"type":"number","title":"Price Usd"},"carat_weight":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Carat Weight","default":1.0},"color":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Color"},"clarity":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Clarity"},"source_name":{"type":"string","title":"Source Name","default":"manual"},"source_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Url"}},"type":"object","required":["gemstone_type","price_usd"],"title":"AdminObservationRequest"},"AdminProfessionalUpsert":{"properties":{"display_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Display Name"},"business_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Business Name"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email"},"phone":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Phone"},"website":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Website"},"blurb":{"anyOf":[{"type":"string","maxLength":300},{"type":"null"}],"title":"Blurb"},"credentials":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Credentials"},"specialties":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Specialties"},"is_jeweler":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Jeweler"},"serves_appraisal":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Serves Appraisal"},"serves_buying":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Serves Buying"},"serves_insurance":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Serves Insurance"},"address_line1":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Address Line1"},"city":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"City"},"region_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Region Code"},"postal_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Postal Code"},"country_code":{"anyOf":[{"type":"string","maxLength":2,"minLength":2},{"type":"null"}],"title":"Country Code"},"lat":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Lat"},"lng":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Lng"},"geocode_source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Geocode Source"},"geocode_confidence":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Geocode Confidence"},"min_value":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Min Value"},"max_value":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Max Value"},"accepts_leads":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Accepts Leads"},"claim_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Claim Status"},"is_active":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Active"},"suppressed":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Suppressed"},"suppression_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Suppression Reason"},"sort_order":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Sort Order"},"source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source"},"source_attribution":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Attribution"},"source_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Url"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"}},"type":"object","title":"AdminProfessionalUpsert","description":"Admin CRUD body. Everything optional on update; display identity fields\nare admin-only on purpose (claiming never edits them)."},"AdminProviderClickRow":{"properties":{"provider_id":{"type":"integer","title":"Provider Id"},"provider":{"type":"string","title":"Provider"},"kind":{"type":"string","title":"Kind"},"clicks":{"type":"integer","title":"Clicks"},"value_routed":{"type":"number","title":"Value Routed"}},"type":"object","required":["provider_id","provider","kind","clicks","value_routed"],"title":"AdminProviderClickRow"},"AgentSwitchCheckIn":{"properties":{"permission":{"anyOf":[{"type":"string","enum":["granted","denied","undetermined","provisional"]},{"type":"null"}],"title":"Permission"},"push_token":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Push Token"}},"type":"object","title":"AgentSwitchCheckIn"},"AgentSwitchIn":{"properties":{"on":{"type":"boolean","title":"On"},"permission":{"anyOf":[{"type":"string","enum":["granted","denied","undetermined","provisional"]},{"type":"null"}],"title":"Permission"},"push_token":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Push Token"},"source":{"type":"string","enum":["settings","first_save","shortcut","ask"],"title":"Source","default":"settings"}},"type":"object","required":["on"],"title":"AgentSwitchIn"},"AgentSwitchOut":{"properties":{"choice":{"type":"string","enum":["on","off","unset"],"title":"Choice"},"active":{"type":"boolean","title":"Active"},"ready":{"type":"boolean","title":"Ready"},"paused":{"type":"boolean","title":"Paused"},"reason":{"anyOf":[{"type":"string","enum":["no_permission","no_token","push_off"]},{"type":"null"}],"title":"Reason"},"asked":{"type":"boolean","title":"Asked"}},"type":"object","required":["choice","active","ready","paused","asked"],"title":"AgentSwitchOut"},"AllocationBlock":{"properties":{"by_species":{"items":{"$ref":"#/components/schemas/SpeciesAllocation"},"type":"array","title":"By Species"}},"type":"object","required":["by_species"],"title":"AllocationBlock"},"AlternativeIdentification":{"properties":{"name":{"type":"string","title":"Name"},"confidence":{"type":"integer","title":"Confidence"}},"type":"object","required":["name","confidence"],"title":"AlternativeIdentification","description":"Alternative gemstone identification when confidence is below 85%"},"AlternativeV2":{"properties":{"name":{"type":"string","title":"Name"},"confidence":{"type":"integer","maximum":100.0,"minimum":0.0,"title":"Confidence"}},"type":"object","required":["name","confidence"],"title":"AlternativeV2"},"Analysis":{"properties":{"description":{"type":"string","minLength":30,"title":"Description"},"context":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Context"},"specs":{"items":{"$ref":"#/components/schemas/AnalysisSpec"},"type":"array","maxItems":10,"minItems":4,"title":"Specs"}},"type":"object","required":["description","specs"],"title":"Analysis","description":"Paragraph 1 observes the piece, paragraph 2 places it.\n\n`context` is the market/tradition/design-period paragraph. Optional by\ndesign: the prompt is told to return null rather than reach when there is\nno specific tradition or trade habit tied to what was observed (an\nUnidentified species, a non-gem object). A missing context is a clean\noutcome, so it must never fail validation."},"AnalysisSpec":{"properties":{"label":{"type":"string","title":"Label"},"value":{"type":"string","title":"Value"}},"type":"object","required":["label","value"],"title":"AnalysisSpec"},"AppleAuthRequest":{"properties":{"identity_token":{"type":"string","title":"Identity Token","description":"Apple identity token (JWT) from Sign in with Apple"},"full_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Full Name","description":"Display name — Apple only provides it on the first authorization"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email","description":"Email — Apple only provides it on the first authorization"},"gemstone_ids":{"anyOf":[{"items":{"type":"integer"},"type":"array"},{"type":"null"}],"title":"Gemstone Ids","description":"Optional list of anonymous gemstone IDs to link to the user"},"promo_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Promo Code","description":"Optional promo code to redeem on signup (LNK-PROMO)"}},"type":"object","required":["identity_token"],"title":"AppleAuthRequest"},"AppreciationBlock":{"properties":{"value_at_save":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Value At Save"},"value_now":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Value Now"},"change_abs":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Change Abs"},"change_pct":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Change Pct"}},"type":"object","title":"AppreciationBlock"},"ArticleResponse":{"properties":{"id":{"type":"string","title":"Id"},"title":{"type":"string","title":"Title"},"category":{"type":"string","title":"Category"},"excerpt":{"type":"string","title":"Excerpt"},"content":{"type":"string","title":"Content"},"author":{"type":"string","title":"Author"},"published_at":{"type":"string","format":"date-time","title":"Published At"},"read_time":{"type":"integer","title":"Read Time"},"imageUrl":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Imageurl"},"tags":{"items":{"type":"string"},"type":"array","title":"Tags"}},"type":"object","required":["id","title","category","excerpt","content","author","published_at","read_time","tags"],"title":"ArticleResponse"},"AsksBlock":{"properties":{"count":{"type":"integer","title":"Count"},"median":{"type":"number","title":"Median"},"p25":{"type":"number","title":"P25"},"p75":{"type":"number","title":"P75"},"observed_through":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Observed Through"}},"type":"object","required":["count","median","p25","p75"],"title":"AsksBlock","description":"What is listed RIGHT NOW. An observation, not a price claim. Unbanded and\nungated on purpose: its honesty comes from being labelled asks."},"AtomizeRequest":{"properties":{"hero_piece_id":{"type":"integer","title":"Hero Piece Id"},"platforms":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Platforms"}},"type":"object","required":["hero_piece_id"],"title":"AtomizeRequest"},"AttributionBucket":{"properties":{"campaign":{"type":"string","title":"Campaign"},"source":{"type":"string","title":"Source"},"medium":{"type":"string","title":"Medium"},"signups":{"type":"integer","title":"Signups"},"scanned":{"type":"integer","title":"Scanned"},"paid":{"type":"integer","title":"Paid"}},"type":"object","required":["campaign","source","medium","signups","scanned","paid"],"title":"AttributionBucket"},"AttributionPayload":{"properties":{"source":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Source","description":"utm_source / referrer source"},"medium":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Medium","description":"utm_medium"},"campaign":{"anyOf":[{"type":"string","maxLength":300},{"type":"null"}],"title":"Campaign","description":"utm_campaign / ct token"},"ref":{"anyOf":[{"type":"string","maxLength":300},{"type":"null"}],"title":"Ref","description":"ref shortcode from deep links"},"captured_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Captured At","description":"When the client first captured this"}},"type":"object","title":"AttributionPayload"},"AttributionResponse":{"properties":{"captured":{"type":"boolean","title":"Captured"},"attribution_source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Attribution Source"},"attribution_medium":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Attribution Medium"},"attribution_campaign":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Attribution Campaign"},"attribution_ref":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Attribution Ref"},"attribution_captured_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Attribution Captured At"}},"type":"object","required":["captured"],"title":"AttributionResponse"},"Authenticity":{"properties":{"state":{"type":"string","enum":["ok","warn"],"title":"State"},"message":{"type":"string","maxLength":240,"minLength":1,"title":"Message"},"verify_link":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Verify Link"}},"type":"object","required":["state","message"],"title":"Authenticity"},"BlockRequest":{"properties":{"comment_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Comment Id"},"user_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"User Id"}},"type":"object","title":"BlockRequest","description":"Block a member.\n\nThe app identifies them by the COMMENT it is looking at, not by a user id,\nbecause the public comment payload deliberately carries no author id — an\nenumerable member id on an unauthenticated endpoint is not something the\nblock button needs to exist. `user_id` remains for admin and internal\ncallers that already hold one."},"BoardCommentListResponse":{"properties":{"entry_id":{"type":"integer","title":"Entry Id"},"seed_prompt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Seed Prompt"},"total":{"type":"integer","title":"Total"},"comments":{"items":{"$ref":"#/components/schemas/BoardCommentOut"},"type":"array","title":"Comments"}},"type":"object","required":["entry_id","total"],"title":"BoardCommentListResponse"},"BoardCommentOut":{"properties":{"id":{"type":"integer","title":"Id"},"entry_id":{"type":"integer","title":"Entry Id"},"body":{"type":"string","title":"Body"},"byline":{"type":"string","title":"Byline"},"is_anonymous":{"type":"boolean","title":"Is Anonymous"},"is_mine":{"type":"boolean","title":"Is Mine","default":false},"is_owner":{"type":"boolean","title":"Is Owner","default":false},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","entry_id","body","byline","is_anonymous","created_at"],"title":"BoardCommentOut"},"BoardEntryOut":{"properties":{"id":{"type":"integer","title":"Id"},"piece":{"$ref":"#/components/schemas/BoardPiece"},"cover_image_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Cover Image Id"},"byline":{"type":"string","title":"Byline"},"is_anonymous":{"type":"boolean","title":"Is Anonymous"},"is_mine":{"type":"boolean","title":"Is Mine","default":false},"seed_prompt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Seed Prompt"},"vote_count":{"type":"integer","title":"Vote Count","default":0},"comment_count":{"type":"integer","title":"Comment Count","default":0},"has_voted":{"type":"boolean","title":"Has Voted","default":false},"rank":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Rank"},"score":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Score"},"won_week":{"type":"boolean","title":"Won Week","default":false},"week_start":{"type":"string","format":"date","title":"Week Start"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","piece","byline","is_anonymous","week_start","created_at"],"title":"BoardEntryOut"},"BoardImage":{"properties":{"id":{"type":"integer","title":"Id"},"image_url":{"type":"string","title":"Image Url"},"image_role":{"type":"string","title":"Image Role","default":"unknown"}},"type":"object","required":["id","image_url"],"title":"BoardImage"},"BoardListResponse":{"properties":{"week_start":{"type":"string","format":"date","title":"Week Start"},"closes_in_seconds":{"type":"integer","title":"Closes In Seconds"},"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"page_size":{"type":"integer","title":"Page Size"},"entries":{"items":{"$ref":"#/components/schemas/BoardEntryOut"},"type":"array","title":"Entries"}},"type":"object","required":["week_start","closes_in_seconds","total","page","page_size"],"title":"BoardListResponse"},"BoardPiece":{"properties":{"id":{"type":"integer","title":"Id"},"main_heading":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Main Heading"},"sub_heading":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sub Heading"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"gem_species":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Gem Species"},"jewelry_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Jewelry Type"},"metal_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Metal Type"},"primary_stone":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Primary Stone"},"carat_estimate":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Carat Estimate"},"color_grade":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Color Grade"},"clarity_grade":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Clarity Grade"},"cut_grade":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cut Grade"},"cut_shape":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cut Shape"},"origin_grade":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Origin Grade"},"treatment_grade":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Treatment Grade"},"transparency_estimate":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Transparency Estimate"},"estimated_value":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Estimated Value"},"images":{"items":{"$ref":"#/components/schemas/BoardImage"},"type":"array","title":"Images"}},"type":"object","required":["id"],"title":"BoardPiece","description":"The publishable projection of a scanned piece.\n\nCarries ONE price — `estimated_value` — and not the tier breakdown that\nproduced it. Comparables are excluded outright: they are a subscriber\nsurface, and a public card is the last place that should be relitigating\nwhich comp links still resolve."},"Body_dealer_scan_api_v1_gems_dealer_scan_post":{"properties":{"images":{"items":{"type":"string","format":"binary"},"type":"array","title":"Images"},"item_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Item Type"},"dealer_context":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Dealer Context"}},"type":"object","required":["images"],"title":"Body_dealer_scan_api_v1_gems_dealer_scan_post"},"Body_import_market_data_api_v1_market_import_post":{"properties":{"file":{"type":"string","format":"binary","title":"File"}},"type":"object","required":["file"],"title":"Body_import_market_data_api_v1_market_import_post"},"Body_import_prospects_csv_api_v1_gtm_prospects_import_post":{"properties":{"source":{"type":"string","title":"Source"},"imported_by":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Imported By"},"file":{"type":"string","format":"binary","title":"File"}},"type":"object","required":["source","file"],"title":"Body_import_prospects_csv_api_v1_gtm_prospects_import_post"},"Body_save_scan_to_collection_api_v1_gems_save_collection_post":{"properties":{"gemstone_ids":{"items":{"type":"integer"},"type":"array","title":"Gemstone Ids"}},"type":"object","required":["gemstone_ids"],"title":"Body_save_scan_to_collection_api_v1_gems_save_collection_post"},"Body_scan_gemstone_endpoint_api_v1_gems_scan_post":{"properties":{"images":{"items":{"type":"string","format":"binary"},"type":"array","title":"Images"},"edge_hint":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Edge Hint"},"realtime_brand_identification":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Realtime Brand Identification"},"item_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Item Id"},"scan_intent":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Scan Intent"},"progress_token":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Progress Token"}},"type":"object","required":["images"],"title":"Body_scan_gemstone_endpoint_api_v1_gems_scan_post"},"Body_submit_claim_api_v1_network_claim__token__post":{"properties":{"email":{"type":"string","title":"Email"},"phone":{"type":"string","title":"Phone","default":""},"website":{"type":"string","title":"Website","default":""},"blurb":{"type":"string","title":"Blurb","default":""},"serves_appraisal":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Serves Appraisal"},"serves_buying":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Serves Buying"},"accepts_leads":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Accepts Leads"},"represents":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Represents"}},"type":"object","required":["email"],"title":"Body_submit_claim_api_v1_network_claim__token__post"},"Body_tray_scan_api_v1_gems_tray_scan_post":{"properties":{"image":{"type":"string","format":"binary","title":"Image"},"max_stones":{"type":"integer","title":"Max Stones","default":30}},"type":"object","required":["image"],"title":"Body_tray_scan_api_v1_gems_tray_scan_post"},"Body_update_profile_api_v1_profile_put":{"properties":{"first_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"First Name"},"last_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Name"},"mobile_number":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mobile Number"},"phone_country_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Phone Country Code"},"avatar":{"anyOf":[{"type":"string","format":"binary"},{"type":"null"}],"title":"Avatar"}},"type":"object","title":"Body_update_profile_api_v1_profile_put"},"Body_upload_gem_image_api_v1_gems_upload_post":{"properties":{"gem_id":{"type":"integer","title":"Gem Id"},"file":{"type":"string","format":"binary","title":"File"}},"type":"object","required":["gem_id","file"],"title":"Body_upload_gem_image_api_v1_gems_upload_post"},"Body_upload_voice_note_api_v1_gtm_demo_voice_note_post":{"properties":{"prospect_id":{"type":"integer","title":"Prospect Id"},"call_duration_min":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Call Duration Min"},"file":{"type":"string","format":"binary","title":"File"}},"type":"object","required":["prospect_id","file"],"title":"Body_upload_voice_note_api_v1_gtm_demo_voice_note_post"},"BootstrapRequest":{"properties":{"dealer_customer_id":{"type":"string","title":"Dealer Customer Id"},"prospect_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Prospect Id"},"plan_tier":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Plan Tier"},"mrr":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Mrr"}},"type":"object","required":["dealer_customer_id"],"title":"BootstrapRequest"},"BrandIdentificationBlock":{"properties":{"brand":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Brand"},"product_line":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Product Line"},"recognition_basis":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Recognition Basis"},"confidence":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Confidence","default":0},"evidence":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Evidence"}},"type":"object","title":"BrandIdentificationBlock","description":"Luxury-house attribution from design language / signature. [LNK-BRAND]\n\nValues are pre-normalized by app.services.brand_vocab (canonical names\nonly, confidence clamped 0-100). Lenient here on purpose — a malformed\nblob must never fail a scan."},"BreakdownBucket":{"properties":{"key":{"type":"string","title":"Key"},"count":{"type":"integer","title":"Count"},"mrr_cents":{"type":"integer","title":"Mrr Cents"}},"type":"object","required":["key","count","mrr_cents"],"title":"BreakdownBucket"},"BroadcastRequest":{"properties":{"title":{"type":"string","maxLength":120,"minLength":1,"title":"Title"},"body":{"type":"string","maxLength":300,"minLength":1,"title":"Body"},"data":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Data"},"dry_run":{"type":"boolean","title":"Dry Run","default":true},"ref":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"Ref","description":"dedupe tag; users already sent this ref are skipped"}},"type":"object","required":["title","body"],"title":"BroadcastRequest"},"BulkEnrollRequest":{"properties":{"sequence_id":{"type":"integer","title":"Sequence Id"},"prospect_filter":{"type":"object","title":"Prospect Filter"},"daily_cap":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Daily Cap"},"dry_run":{"type":"boolean","title":"Dry Run","default":false}},"type":"object","required":["sequence_id","prospect_filter"],"title":"BulkEnrollRequest"},"BulkEnrollResponse":{"properties":{"matched_prospects":{"type":"integer","title":"Matched Prospects"},"enrolled":{"type":"integer","title":"Enrolled"},"skipped":{"type":"integer","title":"Skipped"},"skip_reasons":{"additionalProperties":{"type":"integer"},"type":"object","title":"Skip Reasons"},"dry_run":{"type":"boolean","title":"Dry Run"}},"type":"object","required":["matched_prospects","enrolled","skipped","skip_reasons","dry_run"],"title":"BulkEnrollResponse"},"CancelFeedbackRequest":{"properties":{"reason":{"type":"string","enum":["job_done","too_expensive","not_accurate","values_inconsistent","found_other_app","other"],"title":"Reason"},"detail":{"anyOf":[{"type":"string","maxLength":1000},{"type":"null"}],"title":"Detail"},"platform":{"anyOf":[{"type":"string","maxLength":16},{"type":"null"}],"title":"Platform"}},"type":"object","required":["reason"],"title":"CancelFeedbackRequest"},"CapabilitiesOut":{"properties":{"reminders":{"type":"boolean","title":"Reminders"},"discoveries":{"type":"boolean","title":"Discoveries"},"cards":{"items":{"type":"string"},"type":"array","title":"Cards","default":[]}},"type":"object","required":["reminders","discoveries"],"title":"CapabilitiesOut"},"CaratEstimate":{"properties":{"low":{"type":"number","title":"Low","default":0.0},"high":{"type":"number","title":"High","default":0.0},"best":{"type":"number","title":"Best","default":0.0},"confidence":{"type":"integer","title":"Confidence","default":0},"range_min":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Range Min"},"range_max":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Range Max"}},"type":"object","title":"CaratEstimate","description":"Structured carat weight estimate from range.\n\nTwo producers write this column and they do NOT use the same key names\n(LNK-CARATRANGE, 2026-08-21). The legacy quick-scan path emits\n{low, high, best, confidence}; scan_v2 emits\n{length_mm, width_mm, depth_mm, best, range_min, range_max}. Because\npydantic ignores unknown keys, every scan_v2 row deserialized here lost\nits range entirely and shipped low=0/high=0 — 100% of the last 500 scans\naudited 2026-08-21. `best` survived only because the key name happens to\nmatch.\n\nBoth spellings are now carried and kept in sync by\n`normalize_carat_estimate`, so `GET /gems/{id}/details` returns the same\nrange the inline scan response did. `confidence` stays 0 when the\nproducer did not emit one — scan_v2 has no carat confidence and inventing\none would be worse than admitting we lack it."},"CaratEstimateV2":{"properties":{"length_mm":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Length Mm"},"width_mm":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Width Mm"},"depth_mm":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Depth Mm"},"best":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Best"},"range_min":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Range Min"},"range_max":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Range Max"}},"type":"object","title":"CaratEstimateV2"},"CardContentOut":{"properties":{"title":{"type":"string","title":"Title"},"subtitle":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Subtitle"},"photo_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Photo Url"},"facts":{"items":{"$ref":"#/components/schemas/CardFactOut"},"type":"array","title":"Facts"},"stories":{"items":{"$ref":"#/components/schemas/StoryOut"},"type":"array","title":"Stories"},"people":{"items":{"$ref":"#/components/schemas/PersonOut"},"type":"array","title":"People"},"value":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Value"},"note":{"type":"string","title":"Note"}},"type":"object","required":["title","facts","stories","people","note"],"title":"CardContentOut"},"CardFactOut":{"properties":{"key":{"type":"string","title":"Key"},"label":{"type":"string","title":"Label"},"value":{"type":"string","title":"Value"},"basis":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Basis"},"note":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Note"},"price":{"type":"boolean","title":"Price","default":false},"on":{"type":"boolean","title":"On","default":true}},"type":"object","required":["key","label","value"],"title":"CardFactOut"},"CardSelection":{"properties":{"facts":{"items":{"type":"string"},"type":"array","maxItems":30,"title":"Facts"},"stories":{"items":{"type":"integer"},"type":"array","maxItems":30,"title":"Stories"},"people":{"items":{"type":"integer"},"type":"array","maxItems":30,"title":"People"},"photo":{"type":"boolean","title":"Photo","default":true},"prices":{"type":"boolean","title":"Prices","default":false}},"type":"object","title":"CardSelection"},"CareCheckIn":{"properties":{"entry_id":{"type":"string","maxLength":64,"minLength":1,"title":"Entry Id"},"field":{"type":"string","maxLength":64,"minLength":1,"title":"Field"},"verdict":{"type":"string","enum":["ok","reject"],"title":"Verdict"},"reviewer":{"type":"string","maxLength":64,"minLength":1,"title":"Reviewer"},"note":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Note"},"fingerprint":{"anyOf":[{"type":"string","maxLength":16},{"type":"null"}],"title":"Fingerprint"},"bank":{"type":"string","enum":["care","refresh","detail","story","tradition","collection"],"title":"Bank","default":"care"}},"type":"object","required":["entry_id","field","verdict","reviewer"],"title":"CareCheckIn"},"ChartGenerateRequest":{"properties":{"chart_type":{"type":"string","title":"Chart Type"},"query_spec":{"type":"object","title":"Query Spec"},"aspect":{"type":"string","title":"Aspect","default":"1:1"},"title":{"type":"string","title":"Title"},"subtitle":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Subtitle"},"include_watermark":{"type":"boolean","title":"Include Watermark","default":true}},"type":"object","required":["chart_type","query_spec","title"],"title":"ChartGenerateRequest"},"ChartGenerateResponse":{"properties":{"s3_url":{"type":"string","title":"S3 Url"},"chart_type":{"type":"string","title":"Chart Type"},"aspect":{"type":"string","title":"Aspect"},"generated_at":{"type":"string","format":"date-time","title":"Generated At"}},"type":"object","required":["s3_url","chart_type","aspect","generated_at"],"title":"ChartGenerateResponse"},"ChatHistoryResponse":{"properties":{"gemstone_id":{"type":"integer","title":"Gemstone Id"},"messages":{"items":{"$ref":"#/components/schemas/MessageHistoryItem"},"type":"array","title":"Messages"},"total_messages":{"type":"integer","title":"Total Messages"}},"type":"object","required":["gemstone_id","messages","total_messages"],"title":"ChatHistoryResponse","description":"Response schema for chat history"},"ChatMessageRequest":{"properties":{"message":{"type":"string","title":"Message"}},"type":"object","required":["message"],"title":"ChatMessageRequest","description":"Request schema for sending a chat message to refine gemstone data"},"ChatMessageResponse":{"properties":{"id":{"type":"integer","title":"Id"},"user_message":{"type":"string","title":"User Message"},"ai_message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ai Message"},"was_accepted":{"type":"boolean","title":"Was Accepted"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","user_message","was_accepted","created_at"],"title":"ChatMessageResponse","description":"Response schema after sending a chat message (matches MessageHistoryItem)"},"ClarityEstimate":{"properties":{"grade":{"type":"string","title":"Grade","default":"Eye Clean"},"confidence":{"type":"integer","title":"Confidence","default":0}},"type":"object","title":"ClarityEstimate","description":"AI-estimated clarity grade from photos"},"ClarityEstimateV2":{"properties":{"grade":{"type":"string","title":"Grade"},"confidence":{"type":"integer","maximum":100.0,"minimum":0.0,"title":"Confidence","default":0}},"type":"object","required":["grade"],"title":"ClarityEstimateV2"},"CollectionAnalyticsResponse":{"properties":{"appreciation":{"$ref":"#/components/schemas/AppreciationBlock"},"movers":{"$ref":"#/components/schemas/app__schemas__chart_data__MoversBlock"},"allocation":{"$ref":"#/components/schemas/AllocationBlock"},"vs_market":{"$ref":"#/components/schemas/VsMarketBlock"}},"type":"object","required":["appreciation","movers","allocation","vs_market"],"title":"CollectionAnalyticsResponse"},"CollectionIn":{"properties":{"slug":{"type":"string","pattern":"^[A-Za-z0-9._-]{1,160}$","title":"Slug"},"data":{"type":"object","title":"Data"}},"type":"object","required":["slug","data"],"title":"CollectionIn"},"CollectionInsightsResponse":{"properties":{"as_of":{"type":"string","title":"As Of"},"totals":{"anyOf":[{"$ref":"#/components/schemas/InsightsTotals"},{"type":"null"}]},"percentile":{"anyOf":[{"$ref":"#/components/schemas/InsightsPercentile"},{"type":"null"}]},"superlatives":{"anyOf":[{"items":{"$ref":"#/components/schemas/InsightsSuperlative"},"type":"array"},{"type":"null"}],"title":"Superlatives"},"composition":{"anyOf":[{"items":{"$ref":"#/components/schemas/InsightsCompositionEntry"},"type":"array"},{"type":"null"}],"title":"Composition"},"movement":{"anyOf":[{"$ref":"#/components/schemas/InsightsMovement"},{"type":"null"}]},"gaps":{"anyOf":[{"$ref":"#/components/schemas/InsightsGaps"},{"type":"null"}]},"metals":{"anyOf":[{"items":{"$ref":"#/components/schemas/InsightsMetalSpot"},"type":"array"},{"type":"null"}],"title":"Metals"}},"type":"object","required":["as_of"],"title":"CollectionInsightsResponse"},"CollectionSpeciesSummary":{"properties":{"species":{"type":"string","title":"Species"},"count":{"type":"integer","title":"Count"},"total_value":{"type":"number","title":"Total Value"}},"type":"object","required":["species","count","total_value"],"title":"CollectionSpeciesSummary","description":"One row of the In-Your-Collection cross-link (LNK-SRRD-0605): how many of\nthis species the caller owns and their combined estimated value."},"ColorProfile":{"properties":{"color":{"type":"string","title":"Color"}},"type":"object","required":["color"],"title":"ColorProfile","description":"Primary gemstone color profile"},"ColorRow":{"properties":{"color_grade":{"type":"string","title":"Color Grade"},"weight_ranges":{"items":{"$ref":"#/components/schemas/WeightRangePrice"},"type":"array","title":"Weight Ranges"}},"type":"object","required":["color_grade","weight_ranges"],"title":"ColorRow"},"CombineSamePieceRequest":{"properties":{"into_id":{"type":"integer","title":"Into Id"}},"type":"object","required":["into_id"],"title":"CombineSamePieceRequest"},"CombineSamePieceResponse":{"properties":{"success":{"type":"boolean","title":"Success","default":true},"value_combined":{"type":"boolean","title":"Value Combined"},"gemstone":{"$ref":"#/components/schemas/GemstoneResponse"}},"type":"object","required":["value_combined","gemstone"],"title":"CombineSamePieceResponse"},"CommunityOut":{"properties":{"count":{"type":"integer","title":"Count"},"label":{"type":"string","title":"Label"}},"type":"object","required":["count","label"],"title":"CommunityOut"},"CompListing":{"properties":{"id":{"type":"integer","title":"Id"},"gemstone_type":{"type":"string","title":"Gemstone Type"},"carat_weight":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Carat Weight"},"price_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Price Usd"},"price_per_carat":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Price Per Carat"},"color":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Color"},"color_grade":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Color Grade"},"clarity":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Clarity"},"clarity_grade":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Clarity Grade"},"cut":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cut"},"cut_grade":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cut Grade"},"shape":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Shape"},"origin":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Origin"},"origin_grade":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Origin Grade"},"treatment":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Treatment"},"treatment_grade":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Treatment Grade"},"category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category"},"image_url":{"type":"string","title":"Image Url"},"source_name":{"type":"string","title":"Source Name"},"source_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Url"},"source_site":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Site"},"observation_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Observation Date"}},"type":"object","required":["id","gemstone_type","image_url","source_name"],"title":"CompListing"},"CompListingsResponse":{"properties":{"total":{"type":"integer","title":"Total"},"page_size":{"type":"integer","title":"Page Size"},"offset":{"type":"integer","title":"Offset"},"items":{"items":{"$ref":"#/components/schemas/CompListing"},"type":"array","title":"Items"}},"type":"object","required":["total","page_size","offset","items"],"title":"CompListingsResponse"},"ComparableListing":{"properties":{"price":{"anyOf":[{"type":"number","minimum":0.0},{"type":"null"}],"title":"Price"},"source_name":{"type":"string","maxLength":32,"minLength":1,"title":"Source Name"},"source_url":{"type":"string","title":"Source Url"},"thumbnail_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Thumbnail Url"},"kind":{"type":"string","enum":["listing","category"],"title":"Kind","default":"listing"},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"currency":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Currency"},"price_source":{"anyOf":[{"type":"string","enum":["product_page","unavailable"]},{"type":"null"}],"title":"Price Source"},"checked_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Checked At"},"comparison_notes":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Comparison Notes"}},"type":"object","required":["source_name","source_url"],"title":"ComparableListing","description":"A \"similar for sale\" card.\n\n`kind` discriminates a retrieved product listing from a category-search\nlink (LNK-COMPCIRC). Category links have no observed price and therefore\ncarry `price: None` — they used to be priced off the scan's own estimate,\nwhich shipped the valuation back to the user disguised as market evidence.\nAbsent `kind` (rows persisted before this change) means \"listing\"."},"ComponentRefreshResult":{"properties":{"status":{"type":"string","enum":["updated","held"],"title":"Status"},"reason":{"type":"string","title":"Reason"},"updated_bases":{"items":{"type":"string"},"type":"array","title":"Updated Bases"}},"type":"object","required":["status","reason","updated_bases"],"title":"ComponentRefreshResult"},"ComposeRequest":{"properties":{"brand":{"type":"string","title":"Brand","default":"gemstoneai-dealer"},"dry_run":{"type":"boolean","title":"Dry Run","default":false},"push_to_beehiiv":{"type":"boolean","title":"Push To Beehiiv","default":true}},"type":"object","title":"ComposeRequest"},"Composition":{"properties":{"center_stone":{"anyOf":[{"$ref":"#/components/schemas/CompositionStone"},{"type":"null"}]},"accents":{"items":{"$ref":"#/components/schemas/CompositionAccent"},"type":"array","title":"Accents"},"setting":{"anyOf":[{"$ref":"#/components/schemas/CompositionSetting"},{"type":"null"}]}},"type":"object","title":"Composition"},"CompositionAccent":{"properties":{"type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Type"},"count":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Count"}},"type":"object","title":"CompositionAccent"},"CompositionSetting":{"properties":{"metal":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Metal"},"style":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Style"}},"type":"object","title":"CompositionSetting"},"CompositionStone":{"properties":{"type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Type"},"carat":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Carat"},"color":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Color"},"cut":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cut"},"clarity":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Clarity"}},"type":"object","title":"CompositionStone"},"CompsBlock":{"properties":{"total":{"type":"integer","title":"Total","default":0},"items":{"items":{"$ref":"#/components/schemas/CompListing"},"type":"array","title":"Items","default":[]}},"type":"object","title":"CompsBlock"},"ConditionCheckIn":{"properties":{"gem_id":{"type":"integer","title":"Gem Id"},"key":{"type":"string","maxLength":16,"minLength":16,"pattern":"^[0-9a-f]{16}$","title":"Key"},"verdict":{"type":"string","enum":["real","not_real"],"title":"Verdict"},"reviewer":{"type":"string","maxLength":64,"minLength":1,"title":"Reviewer"},"note":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Note"}},"type":"object","required":["gem_id","key","verdict","reviewer"],"title":"ConditionCheckIn"},"ConsensusTrace":{"properties":{"runs":{"type":"integer","title":"Runs","default":0},"species_agreed":{"type":"boolean","title":"Species Agreed","default":true},"species_votes":{"type":"object","title":"Species Votes"},"named_votes":{"type":"integer","title":"Named Votes","default":0},"species_conflict":{"type":"boolean","title":"Species Conflict","default":false},"value_spread":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Value Spread"},"capped":{"type":"boolean","title":"Capped","default":false},"action":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Action"}},"type":"object","title":"ConsensusTrace","description":"Trace of the self-consistency layer (LNK-SELFCON). Records how many\nindependent reads of the same frames were taken and what they disagreed\nabout. Lenient by design — telemetry, never fails a scan."},"ConsumerActivityItem":{"properties":{"at":{"type":"string","format":"date-time","title":"At"},"event":{"type":"string","title":"Event"},"user_id":{"type":"integer","title":"User Id"},"full_name":{"type":"string","title":"Full Name"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email"},"product_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Product Id"},"store":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Store"},"mrr_cents":{"type":"integer","title":"Mrr Cents","default":0}},"type":"object","required":["at","event","user_id","full_name"],"title":"ConsumerActivityItem"},"ConsumerActivityResponse":{"properties":{"days":{"type":"integer","title":"Days"},"items":{"items":{"$ref":"#/components/schemas/ConsumerActivityItem"},"type":"array","title":"Items"}},"type":"object","required":["days","items"],"title":"ConsumerActivityResponse"},"ConsumerAttribution":{"properties":{"days":{"type":"integer","title":"Days"},"since":{"type":"string","format":"date-time","title":"Since"},"total_signups":{"type":"integer","title":"Total Signups"},"buckets":{"items":{"$ref":"#/components/schemas/AttributionBucket"},"type":"array","title":"Buckets"}},"type":"object","required":["days","since","total_signups","buckets"],"title":"ConsumerAttribution"},"ConsumerBreakdown":{"properties":{"total_paying":{"type":"integer","title":"Total Paying"},"total_churning":{"type":"integer","title":"Total Churning"},"by_store":{"items":{"$ref":"#/components/schemas/BreakdownBucket"},"type":"array","title":"By Store"},"by_billing_period":{"items":{"$ref":"#/components/schemas/BreakdownBucket"},"type":"array","title":"By Billing Period"},"by_product":{"items":{"$ref":"#/components/schemas/BreakdownBucket"},"type":"array","title":"By Product"}},"type":"object","required":["total_paying","total_churning","by_store","by_billing_period","by_product"],"title":"ConsumerBreakdown"},"ConsumerDetail":{"properties":{"user_id":{"type":"integer","title":"User Id"},"full_name":{"type":"string","title":"Full Name"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email"},"mobile_number":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mobile Number"},"phone_country_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Phone Country Code"},"auth_provider":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Auth Provider"},"member_since":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Member Since"},"is_verified":{"type":"boolean","title":"Is Verified","default":false},"status":{"type":"string","title":"Status"},"plan_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Plan Name"},"plan_display_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Plan Display Name"},"subscription_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Subscription Id"},"billing_period":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Billing Period"},"mrr_cents":{"type":"integer","title":"Mrr Cents","default":0},"currency":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Currency"},"current_period_start":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Current Period Start"},"current_period_end":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Current Period End"},"cancel_at_period_end":{"type":"boolean","title":"Cancel At Period End","default":false},"scans_used_this_month":{"type":"integer","title":"Scans Used This Month","default":0},"scan_count_total":{"type":"integer","title":"Scan Count Total","default":0},"scans_saved_total":{"type":"integer","title":"Scans Saved Total","default":0},"last_scan_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Scan At"},"tenure_months":{"type":"number","title":"Tenure Months","default":0.0},"ltv_estimate_cents":{"type":"integer","title":"Ltv Estimate Cents","default":0},"store":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Store"},"product_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Product Id"},"entitlement_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Entitlement Id"},"auto_renew_status":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Auto Renew Status"},"revenuecat_app_user_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Revenuecat App User Id"},"attribution_source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Attribution Source"},"attribution_medium":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Attribution Medium"},"attribution_campaign":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Attribution Campaign"},"attribution_ref":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Attribution Ref"},"attribution_captured_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Attribution Captured At"}},"type":"object","required":["user_id","full_name","status"],"title":"ConsumerDetail"},"ConsumerListItem":{"properties":{"user_id":{"type":"integer","title":"User Id"},"full_name":{"type":"string","title":"Full Name"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email"},"mobile_number":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mobile Number"},"auth_provider":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Auth Provider"},"member_since":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Member Since"},"status":{"type":"string","title":"Status"},"plan_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Plan Name"},"plan_display_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Plan Display Name"},"billing_period":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Billing Period"},"mrr_cents":{"type":"integer","title":"Mrr Cents","default":0},"scans_used_this_month":{"type":"integer","title":"Scans Used This Month","default":0},"scan_count_total":{"type":"integer","title":"Scan Count Total","default":0},"collection_size":{"type":"integer","title":"Collection Size","default":0},"last_scan_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Scan At"},"current_period_end":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Current Period End"},"cancel_at_period_end":{"type":"boolean","title":"Cancel At Period End","default":false}},"type":"object","required":["user_id","full_name","status"],"title":"ConsumerListItem"},"ConsumerListResponse":{"properties":{"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"page_size":{"type":"integer","title":"Page Size"},"items":{"items":{"$ref":"#/components/schemas/ConsumerListItem"},"type":"array","title":"Items"}},"type":"object","required":["total","page","page_size","items"],"title":"ConsumerListResponse"},"ConsumerStats":{"properties":{"total":{"type":"integer","title":"Total"},"paid":{"type":"integer","title":"Paid"},"free":{"type":"integer","title":"Free"},"churned":{"type":"integer","title":"Churned"},"trialing":{"type":"integer","title":"Trialing"},"comped":{"type":"integer","title":"Comped","default":0},"new_7d":{"type":"integer","title":"New 7D"},"mrr_cents":{"type":"integer","title":"Mrr Cents"},"arr_cents":{"type":"integer","title":"Arr Cents"},"scans_last_7d":{"type":"integer","title":"Scans Last 7D"},"scans_last_30d":{"type":"integer","title":"Scans Last 30D"},"collection_total":{"type":"integer","title":"Collection Total","default":0},"collections_nonempty":{"type":"integer","title":"Collections Nonempty","default":0},"avg_collection_size":{"type":"number","title":"Avg Collection Size","default":0.0},"mrr_unconverted_subs":{"type":"integer","title":"Mrr Unconverted Subs","default":0},"mrr_unconverted_currencies":{"items":{"type":"string"},"type":"array","title":"Mrr Unconverted Currencies"},"fx_as_of":{"type":"string","title":"Fx As Of","default":""}},"type":"object","required":["total","paid","free","churned","trialing","new_7d","mrr_cents","arr_cents","scans_last_7d","scans_last_30d"],"title":"ConsumerStats"},"ContentOutputListResponse":{"properties":{"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"page_size":{"type":"integer","title":"Page Size"},"items":{"items":{"$ref":"#/components/schemas/ContentOutputResponse"},"type":"array","title":"Items"}},"type":"object","required":["total","page","page_size","items"],"title":"ContentOutputListResponse"},"ContentOutputResponse":{"properties":{"id":{"type":"integer","title":"Id"},"hero_piece_id":{"type":"integer","title":"Hero Piece Id"},"platform":{"type":"string","title":"Platform"},"variant_number":{"type":"integer","title":"Variant Number"},"content":{"type":"string","title":"Content"},"assets":{"anyOf":[{"items":{"type":"object"},"type":"array"},{"type":"null"}],"title":"Assets"},"hashtags":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Hashtags"},"cta":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cta"},"subreddit":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Subreddit"},"thread_title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Thread Title"},"status":{"type":"string","title":"Status"},"confidence_score":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Confidence Score"},"reviewed_by":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reviewed By"},"reviewed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Reviewed At"},"regeneration_count":{"type":"integer","title":"Regeneration Count","default":0},"metrics":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Metrics"},"brand":{"type":"string","title":"Brand"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","hero_piece_id","platform","variant_number","content","status","brand","created_at"],"title":"ContentOutputResponse"},"ContentOutputReviewRequest":{"properties":{"status":{"type":"string","title":"Status"},"reviewed_by":{"type":"string","title":"Reviewed By"},"edits":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Edits"},"rejection_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Rejection Reason"}},"type":"object","required":["status","reviewed_by"],"title":"ContentOutputReviewRequest"},"ContentQueueItemResponse":{"properties":{"id":{"type":"integer","title":"Id"},"insight_type":{"type":"string","title":"Insight Type"},"title":{"type":"string","title":"Title"},"narrative":{"type":"string","title":"Narrative"},"data_payload":{"type":"object","title":"Data Payload"},"chart_specs":{"anyOf":[{"items":{"type":"object"},"type":"array"},{"type":"null"}],"title":"Chart Specs"},"publishability_score":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Publishability Score"},"expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Expires At"},"status":{"type":"string","title":"Status"},"priority":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Priority"},"source_signal_ids":{"anyOf":[{"items":{"type":"integer"},"type":"array"},{"type":"null"}],"title":"Source Signal Ids"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","insight_type","title","narrative","data_payload","status","created_at"],"title":"ContentQueueItemResponse"},"ContentQueueListResponse":{"properties":{"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"page_size":{"type":"integer","title":"Page Size"},"items":{"items":{"$ref":"#/components/schemas/ContentQueueItemResponse"},"type":"array","title":"Items"}},"type":"object","required":["total","page","page_size","items"],"title":"ContentQueueListResponse"},"ContentScheduleResponse":{"properties":{"id":{"type":"integer","title":"Id"},"content_output_id":{"type":"integer","title":"Content Output Id"},"platform":{"type":"string","title":"Platform"},"account_handle":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Account Handle"},"scheduled_for":{"type":"string","format":"date-time","title":"Scheduled For"},"published_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Published At"},"external_post_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"External Post Id"},"external_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"External Url"},"status":{"type":"string","title":"Status"},"retry_count":{"type":"integer","title":"Retry Count","default":0},"last_error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Error"},"metrics":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Metrics"},"brand":{"type":"string","title":"Brand"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","content_output_id","platform","scheduled_for","status","brand","created_at"],"title":"ContentScheduleResponse"},"CoverageIntentListResponse":{"properties":{"intents":{"items":{"$ref":"#/components/schemas/CoverageIntentResponse"},"type":"array","title":"Intents"},"coverage_gem_ids":{"items":{"type":"integer"},"type":"array","title":"Coverage Gem Ids"},"appraisal_gem_ids":{"items":{"type":"integer"},"type":"array","title":"Appraisal Gem Ids"}},"type":"object","required":["intents","coverage_gem_ids","appraisal_gem_ids"],"title":"CoverageIntentListResponse"},"CoverageIntentRequest":{"properties":{"kind":{"type":"string","title":"Kind","description":"coverage | appraisal"},"gemstone_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Gemstone Id","description":"Omit for a whole-collection intent"},"note":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Note"}},"type":"object","required":["kind"],"title":"CoverageIntentRequest"},"CoverageIntentResponse":{"properties":{"id":{"type":"integer","title":"Id"},"kind":{"type":"string","title":"Kind"},"gemstone_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Gemstone Id"},"item_value":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Item Value"},"status":{"type":"string","title":"Status"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"message":{"type":"string","title":"Message"}},"type":"object","required":["id","kind","gemstone_id","item_value","status","created_at","message"],"title":"CoverageIntentResponse"},"CoverageProviderListResponse":{"properties":{"kind":{"type":"string","title":"Kind"},"providers":{"items":{"$ref":"#/components/schemas/CoverageProviderResponse"},"type":"array","title":"Providers"},"disclosure":{"type":"string","title":"Disclosure"}},"type":"object","required":["kind","providers","disclosure"],"title":"CoverageProviderListResponse"},"CoverageProviderResponse":{"properties":{"id":{"type":"integer","title":"Id"},"name":{"type":"string","title":"Name"},"url":{"type":"string","title":"Url"},"blurb":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Blurb"},"is_featured":{"type":"boolean","title":"Is Featured"}},"type":"object","required":["id","name","url","blurb","is_featured"],"title":"CoverageProviderResponse"},"CreateCommentRequest":{"properties":{"body":{"type":"string","title":"Body"},"is_anonymous":{"type":"boolean","title":"Is Anonymous","default":false}},"type":"object","required":["body"],"title":"CreateCommentRequest"},"CreateDeviceRequest":{"properties":{"device_id":{"type":"string","title":"Device Id"},"device_info":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Device Info"}},"type":"object","required":["device_id"],"title":"CreateDeviceRequest","description":"Request to create/register a new device","example":{"device_id":"550e8400-e29b-41d4-a716-446655440000","device_info":{"app_version":"1.2.0","device_model":"Pixel 7 Pro","device_type":"android","os_version":"14.0"}}},"CreateReminderIn":{"properties":{"gem_id":{"type":"integer","title":"Gem Id"},"kind":{"const":"reminder","title":"Kind","default":"reminder"},"due_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Due At"},"timezone":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}],"title":"Timezone"},"purpose":{"anyOf":[{"type":"string","maxLength":32},{"type":"null"}],"title":"Purpose"},"note":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Note"}},"type":"object","required":["gem_id"],"title":"CreateReminderIn"},"CustomerOnboardingListResponse":{"properties":{"total":{"type":"integer","title":"Total"},"items":{"items":{"$ref":"#/components/schemas/CustomerOnboardingResponse"},"type":"array","title":"Items"}},"type":"object","required":["total","items"],"title":"CustomerOnboardingListResponse"},"CustomerOnboardingResponse":{"properties":{"id":{"type":"integer","title":"Id"},"dealer_customer_id":{"type":"string","title":"Dealer Customer Id"},"prospect_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Prospect Id"},"onboarding_started_at":{"type":"string","format":"date-time","title":"Onboarding Started At"},"milestones_hit":{"items":{"type":"object"},"type":"array","title":"Milestones Hit","default":[]},"onboarding_completed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Onboarding Completed At"},"churn_risk_score":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Churn Risk Score"},"churn_risk_updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Churn Risk Updated At"},"plan_tier":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Plan Tier"},"mrr":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mrr"},"nps_score":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Nps Score"},"testimonial_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Testimonial Status"}},"type":"object","required":["id","dealer_customer_id","onboarding_started_at"],"title":"CustomerOnboardingResponse"},"DemoBriefResponse":{"properties":{"prospect_id":{"type":"integer","title":"Prospect Id"},"generated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Generated At"},"background_sentences":{"items":{"type":"string"},"type":"array","title":"Background Sentences","default":[]},"probable_pain_points":{"items":{"type":"string"},"type":"array","title":"Probable Pain Points","default":[]},"recommended_demo_flow":{"items":{"type":"string"},"type":"array","title":"Recommended Demo Flow","default":[]},"likely_objections":{"items":{"type":"object"},"type":"array","title":"Likely Objections","default":[]},"stones_to_highlight":{"items":{"type":"string"},"type":"array","title":"Stones To Highlight","default":[]},"pricing_anchor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pricing Anchor"},"opener":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Opener"},"red_flags":{"items":{"type":"string"},"type":"array","title":"Red Flags","default":[]},"demo_tenant_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Demo Tenant Url"},"event_start":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Event Start"}},"type":"object","required":["prospect_id"],"title":"DemoBriefResponse","description":"Returned by GET /demo/briefs/{prospect_id} — reads the most recent demo_prep_generated signal."},"DemoPrepRequest":{"properties":{"prospect_id":{"type":"integer","title":"Prospect Id"},"event_start":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Event Start"},"event_uri":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Event Uri"},"force_refresh_enrichment":{"type":"boolean","title":"Force Refresh Enrichment","default":false}},"type":"object","required":["prospect_id"],"title":"DemoPrepRequest","description":"Manual trigger (admin UI); Calendly webhook has its own path."},"DemoPrepResponse":{"properties":{"prospect_id":{"type":"integer","title":"Prospect Id"},"job_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Job Id"},"queued_at":{"type":"string","format":"date-time","title":"Queued At"}},"type":"object","required":["prospect_id","queued_at"],"title":"DemoPrepResponse"},"DeviceResponse":{"properties":{"id":{"type":"integer","title":"Id"},"scan_limit":{"type":"integer","title":"Scan Limit"},"scans_remaining":{"type":"integer","title":"Scans Remaining"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","scan_limit","scans_remaining","created_at"],"title":"DeviceResponse","description":"Response after device creation/registration"},"DimensionsEstimate":{"properties":{"length_mm":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Length Mm"},"width_mm":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Width Mm"},"depth_mm":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Depth Mm"},"confidence":{"type":"integer","title":"Confidence","default":0}},"type":"object","title":"DimensionsEstimate","description":"AI-estimated physical dimensions from image proportions"},"DimensionsEstimateV2":{"properties":{"length_mm":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Length Mm"},"width_mm":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Width Mm"},"depth_mm":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Depth Mm"},"confidence":{"type":"integer","maximum":100.0,"minimum":0.0,"title":"Confidence","default":0}},"type":"object","title":"DimensionsEstimateV2"},"DismissIn":{"properties":{"ids":{"items":{"type":"integer"},"type":"array","maxItems":20,"minItems":1,"title":"Ids"}},"type":"object","required":["ids"],"title":"DismissIn"},"DistributionItem":{"properties":{"name":{"type":"string","title":"Name"},"count":{"type":"integer","title":"Count"}},"type":"object","required":["name","count"],"title":"DistributionItem"},"DistributionsBlock":{"properties":{"total":{"type":"integer","title":"Total","default":0},"colors":{"items":{"$ref":"#/components/schemas/DistributionItem"},"type":"array","title":"Colors","default":[]},"shapes":{"items":{"$ref":"#/components/schemas/DistributionItem"},"type":"array","title":"Shapes","default":[]},"clarities":{"items":{"$ref":"#/components/schemas/DistributionItem"},"type":"array","title":"Clarities","default":[]},"treatments":{"items":{"$ref":"#/components/schemas/DistributionItem"},"type":"array","title":"Treatments","default":[]}},"type":"object","title":"DistributionsBlock","description":"Specimen attribute breakdowns for a variety, computed from the comp\ncorpus (price_observations, user scans fenced out). Each axis is the\ntop values by listing count; empty axes are omitted by the client."},"EligibleListResponse":{"properties":{"total":{"type":"integer","title":"Total"},"pieces":{"items":{"$ref":"#/components/schemas/EligiblePiece"},"type":"array","title":"Pieces"}},"type":"object","required":["total"],"title":"EligibleListResponse"},"EligiblePiece":{"properties":{"gemstone_id":{"type":"integer","title":"Gemstone Id"},"main_heading":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Main Heading"},"cover_image_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cover Image Url"},"eligible":{"type":"boolean","title":"Eligible"},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason"},"already_on_board":{"type":"boolean","title":"Already On Board","default":false}},"type":"object","required":["gemstone_id","eligible"],"title":"EligiblePiece","description":"One of the caller's own pieces, and whether it may be submitted."},"EmailCampaignCreate":{"properties":{"sequence_id":{"type":"integer","title":"Sequence Id"},"prospect_id":{"type":"integer","title":"Prospect Id"},"start_immediately":{"type":"boolean","title":"Start Immediately","default":true}},"type":"object","required":["sequence_id","prospect_id"],"title":"EmailCampaignCreate"},"EmailCampaignListResponse":{"properties":{"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"page_size":{"type":"integer","title":"Page Size"},"items":{"items":{"$ref":"#/components/schemas/EmailCampaignResponse"},"type":"array","title":"Items"}},"type":"object","required":["total","page","page_size","items"],"title":"EmailCampaignListResponse"},"EmailCampaignResponse":{"properties":{"id":{"type":"integer","title":"Id"},"sequence_id":{"type":"integer","title":"Sequence Id"},"sequence_name":{"type":"string","title":"Sequence Name"},"prospect_id":{"type":"integer","title":"Prospect Id"},"current_step":{"type":"integer","title":"Current Step","default":0},"next_send_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Next Send At"},"status":{"type":"string","title":"Status"},"instantly_campaign_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Instantly Campaign Id"},"started_at":{"type":"string","format":"date-time","title":"Started At"},"completed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Completed At"}},"type":"object","required":["id","sequence_id","sequence_name","prospect_id","status","started_at"],"title":"EmailCampaignResponse"},"EmailLoginRequest":{"properties":{"email":{"type":"string","title":"Email","description":"Email address"},"password":{"type":"string","title":"Password"}},"type":"object","required":["email","password"],"title":"EmailLoginRequest"},"EmailOTPResponse":{"properties":{"message":{"type":"string","title":"Message"},"email":{"type":"string","title":"Email"},"expires_in_minutes":{"type":"integer","title":"Expires In Minutes"},"remaining_attempts":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Remaining Attempts"}},"type":"object","required":["message","email","expires_in_minutes"],"title":"EmailOTPResponse"},"EmailRegisterRequest":{"properties":{"email":{"type":"string","title":"Email","description":"Email address"},"password":{"type":"string","minLength":8,"title":"Password","description":"Password (min 8 chars)"},"first_name":{"type":"string","minLength":1,"title":"First Name"},"last_name":{"type":"string","minLength":1,"title":"Last Name"},"gemstone_ids":{"anyOf":[{"items":{"type":"integer"},"type":"array"},{"type":"null"}],"title":"Gemstone Ids"},"promo_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Promo Code","description":"Optional promo code to redeem on signup (LNK-PROMO)"}},"type":"object","required":["email","password","first_name","last_name"],"title":"EmailRegisterRequest"},"EmailSendResponse":{"properties":{"id":{"type":"integer","title":"Id"},"campaign_id":{"type":"integer","title":"Campaign Id"},"step":{"type":"integer","title":"Step"},"scheduled_for":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Scheduled For"},"sent_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Sent At"},"from_mailbox":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"From Mailbox"},"to_email":{"type":"string","title":"To Email"},"subject":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Subject"},"body":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Body"},"personalization_confidence":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Personalization Confidence"},"personalization_hooks_used":{"anyOf":[{"items":{"type":"object"},"type":"array"},{"type":"null"}],"title":"Personalization Hooks Used"},"opened_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Opened At"},"clicked_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Clicked At"},"replied_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Replied At"},"reply_sentiment":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reply Sentiment"},"bounced":{"type":"boolean","title":"Bounced","default":false},"unsubscribed":{"type":"boolean","title":"Unsubscribed","default":false},"review_state":{"type":"string","title":"Review State","default":"auto_send"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","campaign_id","step","to_email","created_at"],"title":"EmailSendResponse"},"EmailSendReviewRequest":{"properties":{"review_state":{"type":"string","title":"Review State"},"reviewed_by":{"type":"string","title":"Reviewed By"},"edited_subject":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Edited Subject"},"edited_body":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Edited Body"}},"type":"object","required":["review_state","reviewed_by"],"title":"EmailSendReviewRequest"},"EmailSequenceCreate":{"properties":{"name":{"type":"string","title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"target_segment":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Target Segment"},"steps":{"items":{"$ref":"#/components/schemas/EmailSequenceStep"},"type":"array","title":"Steps"},"enabled":{"type":"boolean","title":"Enabled","default":true},"default_mailbox_pool":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Default Mailbox Pool"},"daily_cap":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Daily Cap"}},"type":"object","required":["name","steps"],"title":"EmailSequenceCreate"},"EmailSequenceResponse":{"properties":{"id":{"type":"integer","title":"Id"},"name":{"type":"string","title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"target_segment":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Target Segment"},"steps":{"items":{"type":"object"},"type":"array","title":"Steps"},"enabled":{"type":"boolean","title":"Enabled"},"default_mailbox_pool":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Default Mailbox Pool"},"daily_cap":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Daily Cap"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","name","steps","enabled","created_at","updated_at"],"title":"EmailSequenceResponse"},"EmailSequenceStep":{"properties":{"step":{"type":"integer","title":"Step"},"day_offset":{"type":"integer","title":"Day Offset"},"subject_template":{"type":"string","title":"Subject Template"},"body_template":{"type":"string","title":"Body Template"},"personalization_level":{"type":"string","title":"Personalization Level","default":"medium"},"requires":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Requires"}},"type":"object","required":["step","day_offset","subject_template","body_template"],"title":"EmailSequenceStep"},"EmailSequenceUpdate":{"properties":{"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"target_segment":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Target Segment"},"steps":{"anyOf":[{"items":{"$ref":"#/components/schemas/EmailSequenceStep"},"type":"array"},{"type":"null"}],"title":"Steps"},"enabled":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Enabled"},"default_mailbox_pool":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Default Mailbox Pool"},"daily_cap":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Daily Cap"}},"type":"object","title":"EmailSequenceUpdate"},"EntryIn":{"properties":{"kind":{"type":"string","enum":["story","person"],"title":"Kind"},"text":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Text"},"basis":{"anyOf":[{"type":"string","enum":["recollection","documented"]},{"type":"null"}],"title":"Basis"},"name":{"anyOf":[{"type":"string","maxLength":80},{"type":"null"}],"title":"Name"},"role":{"anyOf":[{"type":"string","enum":["from","for"]},{"type":"null"}],"title":"Role"},"relation":{"anyOf":[{"type":"string","maxLength":40},{"type":"null"}],"title":"Relation"},"from_signals":{"items":{"type":"integer"},"type":"array","maxItems":10,"title":"From Signals"}},"type":"object","required":["kind"],"title":"EntryIn"},"EntryPatch":{"properties":{"text":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Text"},"basis":{"anyOf":[{"type":"string","enum":["recollection","documented"]},{"type":"null"}],"title":"Basis"},"name":{"anyOf":[{"type":"string","maxLength":80},{"type":"null"}],"title":"Name"},"role":{"anyOf":[{"type":"string","enum":["from","for"]},{"type":"null"}],"title":"Role"},"relation":{"anyOf":[{"type":"string","maxLength":40},{"type":"null"}],"title":"Relation"}},"type":"object","title":"EntryPatch"},"EstimateResponse":{"properties":{"variety":{"type":"string","title":"Variety"},"carat":{"type":"number","title":"Carat"},"filters":{"type":"object","title":"Filters","default":{}},"estimate":{"additionalProperties":{"type":"number"},"type":"object","title":"Estimate","default":{}},"per_carat":{"additionalProperties":{"type":"number"},"type":"object","title":"Per Carat","default":{}},"sample_size":{"type":"integer","title":"Sample Size","default":0},"total_matches":{"type":"integer","title":"Total Matches","default":0},"sources":{"type":"integer","title":"Sources","default":0},"confidence":{"type":"number","title":"Confidence","default":0.0}},"type":"object","required":["variety","carat"],"title":"EstimateResponse"},"EstimatedValue":{"properties":{"currency":{"type":"string","title":"Currency","default":"USD"},"best":{"type":"number","title":"Best"},"range_min":{"type":"number","title":"Range Min"},"range_max":{"type":"number","title":"Range Max"},"bases":{"anyOf":[{"$ref":"#/components/schemas/ValueBases"},{"type":"null"}]},"pricing":{"anyOf":[{"$ref":"#/components/schemas/PricingResult"},{"type":"null"}]},"headline_basis":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Headline Basis"}},"type":"object","required":["best","range_min","range_max"],"title":"EstimatedValue","description":"Quick scan estimated value"},"EstimatedValueV2":{"properties":{"currency":{"const":"USD","title":"Currency","default":"USD"},"best":{"type":"number","minimum":0.0,"title":"Best"},"range_min":{"type":"number","minimum":0.0,"title":"Range Min"},"range_max":{"type":"number","minimum":0.0,"title":"Range Max"},"headline_basis":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Headline Basis"},"bases":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Bases"}},"type":"object","required":["best","range_min","range_max"],"title":"EstimatedValueV2","description":"Lean V1-style value estimate — the model's source of truth for value.\n\nReplaces the structured three-tier reconciliation that the model\nwas previously forced to emit. The hybrid eval (LNK-IOP, N=110)\nshowed the tier prompt overpriced jewelry by 2x median; V1-style\nlean valuation recovers 80-93% within-2x accuracy on jewelry.\n\nscan_client.py derives the legacy `value` shape from this for\nback-compat."},"FactIn":{"properties":{"value":{"type":"string","maxLength":120,"minLength":1,"title":"Value"}},"type":"object","required":["value"],"title":"FactIn"},"FactOut":{"properties":{"key":{"type":"string","title":"Key"},"label":{"type":"string","title":"Label"},"value":{"type":"string","title":"Value"},"basis":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Basis"},"at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"At"},"note":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Note"},"quote":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Quote"},"ids":{"items":{"type":"integer"},"type":"array","title":"Ids","default":[]},"editable":{"type":"boolean","title":"Editable","default":false}},"type":"object","required":["key","label","value"],"title":"FactOut"},"FeedbackIn":{"properties":{"verdict":{"type":"string","enum":["interesting","not_relevant","less_like_this","stop","dislike_style","no_shopping","useful","not_a_match"],"title":"Verdict"},"reason":{"anyOf":[{"type":"string","enum":["wrong_type","wrong_material","wrong_style","weak_connection","other"]},{"type":"null"}],"title":"Reason"}},"type":"object","required":["verdict"],"title":"FeedbackIn"},"FindingDetailOut":{"properties":{"id":{"type":"integer","title":"Id"},"gem_id":{"type":"integer","title":"Gem Id"},"gem_ids":{"items":{"type":"integer"},"type":"array","title":"Gem Ids","default":[]},"kind":{"type":"string","title":"Kind"},"title":{"type":"string","title":"Title"},"body":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Body"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"seen":{"type":"boolean","title":"Seen"},"feedback":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Feedback"},"thumbnail_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Thumbnail Url"},"price":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Price"},"price_label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Price Label"},"source_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Name"},"moment":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Moment"},"status":{"type":"string","title":"Status"},"payload":{"type":"object","title":"Payload","default":{}},"feedback_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Feedback Reason"},"piece":{"$ref":"#/components/schemas/PieceOut"},"reminder":{"anyOf":[{"$ref":"#/components/schemas/ReminderOut"},{"type":"null"}]}},"type":"object","required":["id","gem_id","kind","title","created_at","seen","status","piece"],"title":"FindingDetailOut"},"FindingOut":{"properties":{"id":{"type":"integer","title":"Id"},"gem_id":{"type":"integer","title":"Gem Id"},"gem_ids":{"items":{"type":"integer"},"type":"array","title":"Gem Ids","default":[]},"kind":{"type":"string","title":"Kind"},"title":{"type":"string","title":"Title"},"body":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Body"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"seen":{"type":"boolean","title":"Seen"},"feedback":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Feedback"},"thumbnail_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Thumbnail Url"},"price":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Price"},"price_label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Price Label"},"source_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Name"},"moment":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Moment"}},"type":"object","required":["id","gem_id","kind","title","created_at","seen"],"title":"FindingOut"},"FollowupApprovalRequest":{"properties":{"approved":{"type":"boolean","title":"Approved"},"edits":{"anyOf":[{"items":{"$ref":"#/components/schemas/FollowupSequenceItem"},"type":"array"},{"type":"null"}],"title":"Edits"},"approver":{"type":"string","title":"Approver"}},"type":"object","required":["approved","approver"],"title":"FollowupApprovalRequest"},"FollowupDraftResponse":{"properties":{"prospect_id":{"type":"integer","title":"Prospect Id"},"transcript":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Transcript"},"extracted_notes":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Extracted Notes"},"sequence":{"items":{"$ref":"#/components/schemas/FollowupSequenceItem"},"type":"array","title":"Sequence","default":[]},"status":{"type":"string","title":"Status"},"generated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Generated At"}},"type":"object","required":["prospect_id","status"],"title":"FollowupDraftResponse"},"FollowupSequenceItem":{"properties":{"step":{"type":"integer","title":"Step"},"send_in_days":{"type":"integer","title":"Send In Days"},"subject":{"type":"string","title":"Subject"},"body":{"type":"string","title":"Body"}},"type":"object","required":["step","send_in_days","subject","body"],"title":"FollowupSequenceItem"},"ForgetIn":{"properties":{"ids":{"items":{"type":"integer"},"type":"array","maxItems":50,"minItems":1,"title":"Ids"}},"type":"object","required":["ids"],"title":"ForgetIn"},"GemAnalyticsResponse":{"properties":{"total_gems":{"type":"integer","title":"Total Gems"},"total_value":{"type":"number","title":"Total Value"},"top_performer":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Top Performer"},"portfolio_change_1d_pct":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Portfolio Change 1D Pct"},"portfolio_change_7d_pct":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Portfolio Change 7D Pct"},"total_cost_basis_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Total Cost Basis Usd"},"total_unrealized_gain_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Total Unrealized Gain Usd"},"total_unrealized_gain_pct":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Total Unrealized Gain Pct"},"total_current_value":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Total Current Value"}},"type":"object","required":["total_gems","total_value","top_performer"],"title":"GemAnalyticsResponse"},"GemIdentificationBlock":{"properties":{"species":{"type":"string","title":"Species"},"source":{"const":"user","title":"Source"},"off_catalog":{"type":"boolean","title":"Off Catalog","default":false},"corrected_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Corrected At"},"ai_species":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ai Species"},"ai_estimated_value":{"anyOf":[{"$ref":"#/components/schemas/EstimatedValue"},{"type":"null"}]}},"type":"object","required":["species","source"],"title":"GemIdentificationBlock","description":"Additive per-gem \"identification\" block (LNK-IDFIX). Null unless the\nowner has overruled the scan's species, so a client that does not know this\nblock sees exactly what it sees today.\n\n`ai_species` / `ai_estimated_value` are what WE said before the correction,\nkept so the app can show the owner what they changed and so a correction\nnever erases the evidence of the miss."},"GemInvestmentBlock":{"properties":{"purchase_price_usd":{"type":"number","title":"Purchase Price Usd"},"purchase_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Purchase Date"},"unrealized_gain_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Unrealized Gain Usd"},"unrealized_gain_pct":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Unrealized Gain Pct"}},"type":"object","required":["purchase_price_usd"],"title":"GemInvestmentBlock","description":"Additive per-gem \"investment\" block (LNK-MKT2). The whole block is null\nwhen the user never set a purchase price. unrealized_gain_usd is null when\nthe gem has no usable est value; unrealized_gain_pct additionally when the\npurchase price is 0."},"GemListResponse":{"properties":{"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"page_size":{"type":"integer","title":"Page Size"},"gems":{"items":{"$ref":"#/components/schemas/GemstoneResponse"},"type":"array","title":"Gems"}},"type":"object","required":["total","page","page_size","gems"],"title":"GemListResponse"},"GemMarketBlock":{"properties":{"current_value":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Current Value"},"change_pct_since_scan":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Change Pct Since Scan"},"change_pct_7d":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Change Pct 7D"},"index_confidence":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Index Confidence"},"variety":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Variety"},"change_1d_pct":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Change 1D Pct"},"change_7d_pct":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Change 7D Pct"},"confidence_tier":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Confidence Tier"}},"type":"object","title":"GemMarketBlock","description":"Additive market-drift block on saved-gem responses (LNK-DRIFT).\n\ncurrent_value = scan-time anchor (estimated_value.best) × variety index\ndrift since the scan date. The whole block is null when the gem's variety\nisn't tracked by the price index; inside the block each field is\nindependently nullable (current_value is null when the gem has no anchor).\nindex_confidence: \"high\" | \"medium\" | \"low\"."},"GemRecordsBlock":{"properties":{"length_mm":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Length Mm"},"width_mm":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Width Mm"},"depth_mm":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Depth Mm"},"carat":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Carat"},"stone_quantity":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Stone Quantity"},"carat_scope":{"anyOf":[{"type":"string","enum":["per_stone","total"]},{"type":"null"}],"title":"Carat Scope"},"lab_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lab Name"},"certificate_number":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Certificate Number"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"},"reference_number":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reference Number"},"watch_year":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Watch Year"},"box_papers":{"anyOf":[{"type":"string","enum":["full_set","papers","box","none"]},{"type":"null"}],"title":"Box Papers"},"watch_condition":{"anyOf":[{"type":"string","enum":["unworn","excellent","good","worn"]},{"type":"null"}],"title":"Watch Condition"},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updated At"}},"type":"object","title":"GemRecordsBlock","description":"Additive per-gem \"records\" block — facts the OWNER stated about their own\npiece. Null block when they have recorded nothing. Deliberately separate\nfrom the *_estimate fields: these are never AI output and a rescan never\noverwrites them.\n\nThe piece title is not part of this block — PUT /gems/{id} (LNK-GEMRENAME)\nowns renaming and writes main_heading."},"GemValueHistoryResponse":{"properties":{"points":{"items":{"$ref":"#/components/schemas/ValueHistoryPoint"},"type":"array","title":"Points"},"change_pct":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Change Pct"},"index_confidence":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Index Confidence"}},"type":"object","required":["points"],"title":"GemValueHistoryResponse"},"GemstoneDeleteResponse":{"properties":{"success":{"type":"boolean","title":"Success"},"message":{"type":"string","title":"Message"},"deleted_id":{"type":"integer","title":"Deleted Id"}},"type":"object","required":["success","message","deleted_id"],"title":"GemstoneDeleteResponse","description":"Response for gemstone deletion"},"GemstoneImageResponse":{"properties":{"id":{"type":"integer","title":"Id"},"image_url":{"type":"string","title":"Image Url"},"thumb_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Thumb Url"}},"type":"object","required":["id","image_url"],"title":"GemstoneImageResponse"},"GemstoneMarketDetailResponse":{"properties":{"id":{"type":"integer","title":"Id"},"variety":{"type":"string","title":"Variety"},"primary_source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Primary Source"},"characteristics":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Characteristics"},"image_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Image Url"},"value_drivers":{"type":"object","title":"Value Drivers","description":"Value drivers for carat, color, clarity, and cut"},"market_dynamics":{"$ref":"#/components/schemas/MarketDynamics"},"market_insights":{"items":{"type":"string"},"type":"array","title":"Market Insights","description":"List of market insight facts"},"pricing_2025":{"$ref":"#/components/schemas/PricingDetails"},"historical_pricing":{"items":{"$ref":"#/components/schemas/HistoricalPricing"},"type":"array","title":"Historical Pricing","description":"Historical pricing from 2020-2024"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","variety","market_dynamics","pricing_2025","created_at","updated_at"],"title":"GemstoneMarketDetailResponse"},"GemstoneResponse":{"properties":{"id":{"type":"integer","title":"Id"},"user_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"User Id"},"scan_saved_to_collection":{"type":"boolean","title":"Scan Saved To Collection","default":false},"main_heading":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Main Heading"},"sub_heading":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sub Heading"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"estimated_value":{"anyOf":[{"$ref":"#/components/schemas/EstimatedValue"},{"type":"string"},{"type":"null"}],"title":"Estimated Value"},"valuation_basis":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Valuation Basis"},"stone_quantity":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Stone Quantity"},"observed_colors":{"anyOf":[{"items":{"type":"object"},"type":"array"},{"type":"null"}],"title":"Observed Colors"},"gem_species":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Gem Species"},"gem_species_confidence":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Gem Species Confidence"},"top_3_candidates":{"anyOf":[{"items":{},"type":"array"},{"type":"null"}],"title":"Top 3 Candidates"},"jewelry_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Jewelry Type"},"metal_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Metal Type"},"metal_detected":{"type":"boolean","title":"Metal Detected","default":false},"gemstone_detected":{"type":"boolean","title":"Gemstone Detected","default":true},"loose_gem":{"type":"boolean","title":"Loose Gem","default":false},"value_trend":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Value Trend","default":"0"},"primary_stone":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Primary Stone"},"scan_quality":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Scan Quality"},"alternatives":{"anyOf":[{"items":{"$ref":"#/components/schemas/AlternativeIdentification"},"type":"array"},{"type":"null"}],"title":"Alternatives"},"origin_estimate":{"anyOf":[{"$ref":"#/components/schemas/OriginEstimate"},{"type":"null"}]},"clarity_estimate":{"anyOf":[{"$ref":"#/components/schemas/ClarityEstimate"},{"type":"null"}]},"treatment_estimate":{"anyOf":[{"$ref":"#/components/schemas/TreatmentEstimate"},{"type":"null"}]},"dimensions_estimate":{"anyOf":[{"$ref":"#/components/schemas/DimensionsEstimate"},{"type":"null"}]},"transparency_estimate":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Transparency Estimate"},"carat_estimate":{"anyOf":[{"$ref":"#/components/schemas/CaratEstimate"},{"type":"null"}]},"carat_scope":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Carat Scope"},"total_carat_weight":{"anyOf":[{},{"type":"null"}],"title":"Total Carat Weight"},"watch":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Watch"},"cut_shape":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cut Shape"},"color_grade":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Color Grade"},"color_grade_confidence":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Color Grade Confidence"},"clarity_grade":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Clarity Grade"},"clarity_grade_confidence":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Clarity Grade Confidence"},"cut_grade":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cut Grade"},"cut_grade_confidence":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Cut Grade Confidence"},"origin_grade":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Origin Grade"},"origin_grade_confidence":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Origin Grade Confidence"},"treatment_grade":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Treatment Grade"},"treatment_grade_confidence":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Treatment Grade Confidence"},"color_profile":{"anyOf":[{"$ref":"#/components/schemas/ColorProfile"},{"type":"null"}]},"jewelry_specifications":{"anyOf":[{"$ref":"#/components/schemas/JewelrySpecifications"},{"type":"null"}]},"stone_specifications":{"anyOf":[{"items":{"$ref":"#/components/schemas/StoneSpec"},"type":"array"},{"type":"null"}],"title":"Stone Specifications"},"about":{"anyOf":[{"$ref":"#/components/schemas/app__schemas__gemstone__About"},{"type":"null"}]},"market_insights":{"anyOf":[{"$ref":"#/components/schemas/app__schemas__gemstone__MarketInsights"},{"type":"null"}]},"value_breakdown":{"anyOf":[{},{"type":"null"}],"title":"Value Breakdown"},"authenticity":{"anyOf":[{},{"type":"null"}],"title":"Authenticity"},"comparables":{"anyOf":[{"items":{},"type":"array"},{"type":"null"}],"title":"Comparables"},"scan_version":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Scan Version"},"analysis":{"anyOf":[{},{"type":"null"}],"title":"Analysis"},"composition":{"anyOf":[{},{"type":"null"}],"title":"Composition"},"value":{"anyOf":[{},{"type":"null"}],"title":"Value"},"confidence":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Confidence"},"specimen_form":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Specimen Form"},"id_agreement":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Id Agreement"},"photo_guidance":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Photo Guidance"},"capture_issue":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Capture Issue"},"stage1_species":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Stage1 Species"},"final_species":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Final Species"},"deep_scan_status":{"type":"string","title":"Deep Scan Status","default":"pending"},"deep_scan_started_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Deep Scan Started At"},"deep_scan_completed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Deep Scan Completed At"},"brand":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Brand"},"product_line":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Product Line"},"brand_source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Brand Source"},"brand_confidence":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Brand Confidence"},"brand_evidence":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Brand Evidence"},"images":{"items":{"$ref":"#/components/schemas/GemstoneImageResponse"},"type":"array","title":"Images","default":[]},"scan_accuracy_feedback":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Scan Accuracy Feedback"},"market":{"anyOf":[{"$ref":"#/components/schemas/GemMarketBlock"},{"type":"null"}]},"investment":{"anyOf":[{"$ref":"#/components/schemas/GemInvestmentBlock"},{"type":"null"}]},"records":{"anyOf":[{"$ref":"#/components/schemas/GemRecordsBlock"},{"type":"null"}]},"identification":{"anyOf":[{"$ref":"#/components/schemas/GemIdentificationBlock"},{"type":"null"}]},"species_source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Species Source"},"species_shortlist":{"anyOf":[{"items":{"$ref":"#/components/schemas/ShortlistOption"},"type":"array"},{"type":"null"}],"title":"Species Shortlist"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","created_at","updated_at"],"title":"GemstoneResponse","description":"Full gemstone response for collection and detail views"},"GemstoneUpdateRequest":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"name_edited":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Name Edited"}},"type":"object","title":"GemstoneUpdateRequest","description":"Body for PUT /api/v1/gems/{gem_id} (LNK-GEMRENAME). Partial update —\nonly fields the client sends change. `name` is the user-facing piece\ntitle, stored on gemstones.main_heading (there is no `name` column).\nUnknown fields are ignored so the app's wider UpdateGemRequest type can\nsend more than the server supports without a 422.\n\n`name_edited` comes from builds that prefill the server's own title, so\nany name they send is the owner's. Without it, a name that matches an old\nbuild's \"<species> <type>\" prefill keeps the scan title (LNK-KEEPTITLE)."},"GoogleAuthRequest":{"properties":{"id_token":{"type":"string","title":"Id Token","description":"Google ID token from client-side sign-in"},"gemstone_ids":{"anyOf":[{"items":{"type":"integer"},"type":"array"},{"type":"null"}],"title":"Gemstone Ids"},"promo_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Promo Code","description":"Optional promo code to redeem on signup (LNK-PROMO)"}},"type":"object","required":["id_token"],"title":"GoogleAuthRequest"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"HeroPieceApproveRequest":{"properties":{"approved_by":{"type":"string","title":"Approved By"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"},"rights_basis":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Rights Basis"},"rights_consent_ref":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Rights Consent Ref"},"source_result_ref":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Result Ref"},"provenance_class":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Provenance Class"}},"type":"object","required":["approved_by"],"title":"HeroPieceApproveRequest"},"HeroPieceGenerateRequest":{"properties":{"mode":{"type":"string","title":"Mode"},"content_queue_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Content Queue Id"},"topic":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Topic"},"source_video_s3_key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Video S3 Key"},"brand":{"type":"string","title":"Brand","default":"gemstoneai-dealer"}},"type":"object","required":["mode"],"title":"HeroPieceGenerateRequest"},"HeroPieceResponse":{"properties":{"id":{"type":"integer","title":"Id"},"mode":{"type":"string","title":"Mode"},"title":{"type":"string","title":"Title"},"topic":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Topic"},"source_content":{"type":"string","title":"Source Content"},"source_video_s3_key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Video S3 Key"},"transcript":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Transcript"},"moments":{"anyOf":[{"items":{"type":"object"},"type":"array"},{"type":"null"}],"title":"Moments"},"chart_refs":{"anyOf":[{"items":{"type":"object"},"type":"array"},{"type":"null"}],"title":"Chart Refs"},"content_queue_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Content Queue Id"},"brand":{"type":"string","title":"Brand"},"word_count":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Word Count"},"generated_at":{"type":"string","format":"date-time","title":"Generated At"},"approved_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Approved At"},"approved_by":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Approved By"},"published_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Published At"},"status":{"type":"string","title":"Status"},"rights_basis":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Rights Basis"},"rights_consent_ref":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Rights Consent Ref"},"source_result_ref":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Result Ref"},"provenance_class":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Provenance Class"}},"type":"object","required":["id","mode","title","source_content","brand","generated_at","status"],"title":"HeroPieceResponse"},"HistoricalPricing":{"properties":{"year":{"type":"integer","title":"Year"},"avg_price":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Avg Price"},"event_note":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Event Note"},"price_k":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Price K","description":"Avg price in $K for graph y-axis"}},"type":"object","required":["year"],"title":"HistoricalPricing"},"HistoryDataPoint":{"properties":{"date":{"type":"string","format":"date","title":"Date"},"avg_per_carat":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Avg Per Carat"},"median_per_carat":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Median Per Carat"},"p10":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"P10"},"p25":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"P25"},"p75":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"P75"},"p90":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"P90"},"observation_count":{"type":"integer","title":"Observation Count","default":0}},"type":"object","required":["date"],"title":"HistoryDataPoint"},"HistoryResponse":{"properties":{"gemstone_type":{"type":"string","title":"Gemstone Type"},"data_points":{"items":{"$ref":"#/components/schemas/HistoryDataPoint"},"type":"array","title":"Data Points","default":[]}},"type":"object","required":["gemstone_type"],"title":"HistoryResponse"},"IdentificationUpdateRequest":{"properties":{"species":{"type":"string","title":"Species"}},"type":"object","required":["species"],"title":"IdentificationUpdateRequest","description":"Body for PATCH /api/v1/gems/{gem_id}/identification.\n\nOne field. Renaming the piece is PUT /gems/{id} (LNK-GEMRENAME) and the\nowner's measurements are PATCH /records (LNK-RECORDS); this endpoint states\nwhat the stone IS, and the valuation follows from it."},"IdentificationUpdateResponse":{"properties":{"gem":{"$ref":"#/components/schemas/GemstoneResponse"},"revalued":{"type":"boolean","title":"Revalued"},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason"},"carat_used":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Carat Used"},"carat_source":{"anyOf":[{"type":"string","enum":["owner","scan"]},{"type":"null"}],"title":"Carat Source"}},"type":"object","required":["gem","revalued"],"title":"IdentificationUpdateResponse","description":"What changed, in the owner's terms: the corrected gem, whether we were\nable to re-price it, and if not, why not.\n\n`revalued` false is not an error. It is the expected outcome for a species\nwe hold no market data for, and the gem deliberately comes back with NO\nestimate rather than the price that belonged to the rejected ID."},"IllustrationResponse":{"properties":{"gem_id":{"type":"integer","title":"Gem Id"},"kind":{"type":"string","enum":["breakdown","studio"],"title":"Kind","default":"breakdown"},"status":{"type":"string","enum":["not_generated","queued","generating","ready","failed","ineligible","outdated"],"title":"Status"},"auto":{"type":"boolean","title":"Auto","default":false},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason"},"illustration_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Illustration Id"},"image_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Image Url"},"thumb_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Thumb Url"},"share_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Share Url"},"created_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Created At"},"completed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Completed At"},"disclosure":{"type":"string","title":"Disclosure","default":"AI illustration based on your photos. Hidden construction is inferred."}},"type":"object","required":["gem_id","status"],"title":"IllustrationResponse","description":"Explore Your Piece state for one piece and kind [LNK-ILLUS].\n\nkind: breakdown (exploded view, inline in the section) or studio (the\nassembled piece on white, the result hero). auto: the client should start\ngeneration itself on not_generated / outdated, without a tap.\n\n`reason` is a stable code: unavailable, unsupported_category, no_main_stone,\nphoto_insufficient, precheck_unavailable, review_failed, provider_error,\nstorage_error, timeout, interrupted, attempt_limit. Image URLs are set only\nwhen status is ready and are opaque to the client."},"ImportIn":{"properties":{"collections":{"items":{"$ref":"#/components/schemas/CollectionIn"},"type":"array","maxItems":50,"title":"Collections"}},"type":"object","required":["collections"],"title":"ImportIn"},"ImportResponse":{"properties":{"success":{"type":"boolean","title":"Success"},"message":{"type":"string","title":"Message"},"imported_count":{"type":"integer","title":"Imported Count"},"updated_count":{"type":"integer","title":"Updated Count"},"failed_count":{"type":"integer","title":"Failed Count"},"errors":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Errors"}},"type":"object","required":["success","message","imported_count","updated_count","failed_count"],"title":"ImportResponse"},"IndexDataItem":{"properties":{"variety":{"type":"string","title":"Variety"},"index_value":{"type":"number","title":"Index Value"},"change_1d_pct":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Change 1D Pct"},"change_7d_pct":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Change 7D Pct"},"change_30d_pct":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Change 30D Pct"},"confidence_tier":{"type":"string","title":"Confidence Tier","default":"moderate"},"explanation_headline":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Explanation Headline"},"sparkline_7d":{"items":{"type":"number"},"type":"array","title":"Sparkline 7D","default":[]},"image_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Image Url"},"tier":{"type":"string","title":"Tier","default":"deep"}},"type":"object","required":["variety","index_value"],"title":"IndexDataItem"},"IndexHistoryPoint":{"properties":{"date":{"type":"string","title":"Date"},"value":{"type":"number","title":"Value"}},"type":"object","required":["date","value"],"title":"IndexHistoryPoint"},"IndexHistoryResponse":{"properties":{"variety":{"type":"string","title":"Variety"},"period":{"type":"string","title":"Period"},"data":{"items":{"$ref":"#/components/schemas/IndexHistoryPoint"},"type":"array","title":"Data","default":[]}},"type":"object","required":["variety","period"],"title":"IndexHistoryResponse"},"IndexListResponse":{"properties":{"as_of":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"As Of"},"data":{"items":{"$ref":"#/components/schemas/IndexDataItem"},"type":"array","title":"Data","default":[]},"metal_prices":{"allOf":[{"$ref":"#/components/schemas/MetalPrices"}],"default":{}},"total":{"type":"integer","title":"Total","default":0},"page":{"type":"integer","title":"Page","default":1},"page_size":{"type":"integer","title":"Page Size","default":20}},"type":"object","title":"IndexListResponse"},"IndexMover":{"properties":{"signal":{"type":"string","title":"Signal"},"label":{"type":"string","title":"Label"},"value":{"type":"number","title":"Value"},"direction":{"type":"string","title":"Direction"}},"type":"object","required":["signal","label","value","direction"],"title":"IndexMover"},"IndexMoversResponse":{"properties":{"variety":{"type":"string","title":"Variety"},"change_pct":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Change Pct"},"explanation_headline":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Explanation Headline"},"movers":{"items":{"$ref":"#/components/schemas/IndexMover"},"type":"array","title":"Movers","default":[]},"signal_breakdown":{"type":"object","title":"Signal Breakdown","default":{}}},"type":"object","required":["variety"],"title":"IndexMoversResponse"},"InputRequest":{"properties":{"attribute":{"type":"string","enum":["carat","length_mm","width_mm","depth_mm","lab_name","certificate_number"],"title":"Attribute"},"state":{"type":"string","enum":["not_asked","asked_not_supplied"],"title":"State","default":"asked_not_supplied"}},"type":"object","required":["attribute"],"title":"InputRequest"},"InsightsBirthstone":{"properties":{"owned_months":{"items":{"type":"integer"},"type":"array","title":"Owned Months"},"missing_months":{"items":{"type":"integer"},"type":"array","title":"Missing Months"},"completion_pct":{"type":"integer","title":"Completion Pct"}},"type":"object","required":["owned_months","missing_months","completion_pct"],"title":"InsightsBirthstone"},"InsightsCompositionEntry":{"properties":{"species":{"type":"string","title":"Species"},"count":{"type":"integer","title":"Count"},"total_value_usd":{"type":"number","title":"Total Value Usd"},"share_pct":{"type":"number","title":"Share Pct"}},"type":"object","required":["species","count","total_value_usd","share_pct"],"title":"InsightsCompositionEntry"},"InsightsGaps":{"properties":{"notable_missing":{"items":{"$ref":"#/components/schemas/InsightsMissingSpecies"},"type":"array","title":"Notable Missing"},"birthstone":{"$ref":"#/components/schemas/InsightsBirthstone"}},"type":"object","required":["notable_missing","birthstone"],"title":"InsightsGaps"},"InsightsMetalSpot":{"properties":{"metal":{"type":"string","title":"Metal"},"spot_usd_oz":{"type":"number","title":"Spot Usd Oz"},"change_7d_pct":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Change 7D Pct"},"change_30d_pct":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Change 30D Pct"}},"type":"object","required":["metal","spot_usd_oz"],"title":"InsightsMetalSpot","description":"Precious-metal spot + real trailing moves (LNK-METALS). Powers per-piece\nmetal-exposure % (a 14K gold band tracks gold spot) and metal-watch insights.\nchange_* are null until the daily fetch has enough stored history."},"InsightsMissingSpecies":{"properties":{"species":{"type":"string","title":"Species"},"category":{"type":"string","title":"Category"},"annual_trend_fraction":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Annual Trend Fraction"},"change_30d_pct":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Change 30D Pct"}},"type":"object","required":["species","category"],"title":"InsightsMissingSpecies"},"InsightsMovement":{"properties":{"portfolio_change_7d_pct":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Portfolio Change 7D Pct"},"portfolio_change_30d_pct":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Portfolio Change 30D Pct"},"market_change_7d_pct":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Market Change 7D Pct"},"market_change_30d_pct":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Market Change 30D Pct"},"per_species":{"items":{"$ref":"#/components/schemas/InsightsSpeciesMovement"},"type":"array","title":"Per Species","default":[]}},"type":"object","title":"InsightsMovement"},"InsightsPercentile":{"properties":{"rank_percent":{"type":"integer","title":"Rank Percent"},"sample_size":{"type":"integer","title":"Sample Size"},"distribution_date":{"type":"string","title":"Distribution Date"},"basis":{"type":"string","title":"Basis","default":"current_value"}},"type":"object","required":["rank_percent","sample_size","distribution_date"],"title":"InsightsPercentile"},"InsightsSpeciesMovement":{"properties":{"species":{"type":"string","title":"Species"},"annual_trend_fraction":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Annual Trend Fraction"},"change_7d_pct":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Change 7D Pct"},"change_30d_pct":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Change 30D Pct"},"confidence":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Confidence"}},"type":"object","required":["species"],"title":"InsightsSpeciesMovement"},"InsightsSuperlative":{"properties":{"species":{"type":"string","title":"Species"},"your_max_usd":{"type":"number","title":"Your Max Usd"},"community_max_usd":{"type":"number","title":"Community Max Usd"},"is_community_high":{"type":"boolean","title":"Is Community High"},"scope":{"type":"string","title":"Scope","default":"all_collectors"}},"type":"object","required":["species","your_max_usd","community_max_usd","is_community_high"],"title":"InsightsSuperlative"},"InsightsTotals":{"properties":{"piece_count":{"type":"integer","title":"Piece Count"},"anchor_value_usd":{"type":"number","title":"Anchor Value Usd"},"current_value_usd":{"type":"number","title":"Current Value Usd"},"currency":{"type":"string","title":"Currency","default":"USD"}},"type":"object","required":["piece_count","anchor_value_usd","current_value_usd"],"title":"InsightsTotals"},"InvestmentUpdateRequest":{"properties":{"purchase_price_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Purchase Price Usd"},"purchase_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Purchase Date"}},"type":"object","title":"InvestmentUpdateRequest","description":"Body for PATCH /api/v1/gems/{gem_id}/investment. Null price clears the\ninvestment data (purchase_date is cleared with it)."},"JewelrySpecifications":{"properties":{"metal":{"anyOf":[{"items":{"$ref":"#/components/schemas/MetalSpec"},"type":"array"},{"type":"null"}],"title":"Metal"},"size":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Size"},"setting":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Setting"},"width":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Width"}},"type":"object","title":"JewelrySpecifications","description":"Jewelry mounting and design specifications"},"LabRequestCreate":{"properties":{"request_type":{"type":"string","title":"Request Type","default":"lab_cert"},"note":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Note"},"cert_image_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cert Image Url"}},"type":"object","title":"LabRequestCreate"},"LabRequestResponse":{"properties":{"id":{"type":"integer","title":"Id"},"gemstone_id":{"type":"integer","title":"Gemstone Id"},"request_type":{"type":"string","title":"Request Type"},"status":{"type":"string","title":"Status"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","gemstone_id","request_type","status","created_at"],"title":"LabRequestResponse"},"LabStatusUpdate":{"properties":{"status":{"type":"string","title":"Status"}},"type":"object","required":["status"],"title":"LabStatusUpdate"},"LadderBand":{"properties":{"size_band":{"type":"string","title":"Size Band"},"label":{"type":"string","title":"Label"},"n_comps":{"type":"integer","title":"N Comps"},"ppc_p25":{"type":"number","title":"Ppc P25"},"ppc_p50":{"type":"number","title":"Ppc P50"},"ppc_p75":{"type":"number","title":"Ppc P75"}},"type":"object","required":["size_band","label","n_comps","ppc_p25","ppc_p50","ppc_p75"],"title":"LadderBand"},"LadderResponse":{"properties":{"species":{"type":"string","title":"Species"},"total_comps":{"type":"integer","title":"Total Comps"},"computed_at":{"type":"string","title":"Computed At"},"ladder":{"items":{"$ref":"#/components/schemas/LadderBand"},"type":"array","title":"Ladder","default":[]}},"type":"object","required":["species","total_comps","computed_at"],"title":"LadderResponse"},"LearnedOut":{"properties":{"ids":{"items":{"type":"integer"},"type":"array","title":"Ids"},"text":{"type":"string","title":"Text"},"field":{"type":"string","title":"Field"},"source":{"type":"string","title":"Source"}},"type":"object","required":["ids","text","field","source"],"title":"LearnedOut"},"LinkCreatedOut":{"properties":{"id":{"type":"integer","title":"Id"},"url":{"type":"string","title":"Url"},"expires_at":{"type":"string","format":"date-time","title":"Expires At"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"shows":{"type":"string","title":"Shows"},"card":{"$ref":"#/components/schemas/CardContentOut"}},"type":"object","required":["id","url","expires_at","created_at","shows","card"],"title":"LinkCreatedOut"},"LinkIn":{"properties":{"facts":{"items":{"type":"string"},"type":"array","maxItems":30,"title":"Facts"},"stories":{"items":{"type":"integer"},"type":"array","maxItems":30,"title":"Stories"},"people":{"items":{"type":"integer"},"type":"array","maxItems":30,"title":"People"},"photo":{"type":"boolean","title":"Photo","default":true},"prices":{"type":"boolean","title":"Prices","default":false},"expires_in_days":{"type":"integer","maximum":365.0,"minimum":1.0,"title":"Expires In Days","default":30}},"type":"object","title":"LinkIn"},"LinkOut":{"properties":{"id":{"type":"integer","title":"Id"},"url":{"type":"string","title":"Url"},"expires_at":{"type":"string","format":"date-time","title":"Expires At"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"shows":{"type":"string","title":"Shows"}},"type":"object","required":["id","url","expires_at","created_at","shows"],"title":"LinkOut"},"MarkAllReadResponse":{"properties":{"marked":{"type":"integer","title":"Marked"}},"type":"object","required":["marked"],"title":"MarkAllReadResponse"},"MarkBand":{"properties":{"size_band":{"type":"string","title":"Size Band"},"label":{"type":"string","title":"Label"},"ppc_p25":{"type":"number","title":"Ppc P25"},"ppc_p50":{"type":"number","title":"Ppc P50"},"ppc_p75":{"type":"number","title":"Ppc P75"},"n":{"type":"integer","title":"N"},"sources":{"type":"integer","title":"Sources"},"mom_pct":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Mom Pct"}},"type":"object","required":["size_band","label","ppc_p25","ppc_p50","ppc_p75","n","sources"],"title":"MarkBand","description":"One measured (variety, carat band) cell from the latest monthly strike."},"MarkBlock":{"properties":{"bands":{"items":{"$ref":"#/components/schemas/MarkBand"},"type":"array","title":"Bands","default":[]},"measured_month":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Measured Month"},"next_strike":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Strike"}},"type":"object","title":"MarkBlock","description":"THE MARK: our measurement, struck monthly. Distinct from `asks`, which is\nwhat sellers are currently listing. Both are true and mean different things.\n\n`bands` is empty when no cell cleared the gates. The client shows the\ncurated reference price in that case, labelled as such, and never a mark."},"MarketDataListResponse":{"properties":{"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"page_size":{"type":"integer","title":"Page Size"},"data":{"items":{"$ref":"#/components/schemas/MarketDataVarietyResponse"},"type":"array","title":"Data"},"as_of":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"As Of"}},"type":"object","required":["total","page","page_size","data"],"title":"MarketDataListResponse"},"MarketDataVarietyResponse":{"properties":{"id":{"type":"integer","title":"Id"},"variety":{"type":"string","title":"Variety"},"avg":{"type":"number","title":"Avg"},"change":{"type":"number","title":"Change"},"min":{"type":"number","title":"Min"},"max":{"type":"number","title":"Max"},"image_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Image Url"},"index_value":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Index Value"},"change_1d_pct":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Change 1D Pct"},"change_7d_pct":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Change 7D Pct"},"change_30d_pct":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Change 30D Pct"},"confidence_tier":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Confidence Tier"},"explanation_headline":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Explanation Headline"},"sparkline_7d":{"items":{"type":"number"},"type":"array","title":"Sparkline 7D","default":[]},"tier":{"type":"string","title":"Tier","default":"deep"}},"type":"object","required":["id","variety","avg","change","min","max"],"title":"MarketDataVarietyResponse"},"MarketDynamics":{"properties":{"supply_description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Supply Description"},"total_global_supply":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Total Global Supply"},"in_circulation":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"In Circulation"},"demand":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Demand"},"recent_trends":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Recent Trends"}},"type":"object","title":"MarketDynamics"},"MarketEstimateResponse":{"properties":{"variety":{"type":"string","title":"Variety"},"carat":{"type":"number","title":"Carat"},"filters":{"type":"object","title":"Filters"},"estimate":{"type":"object","title":"Estimate"},"per_carat":{"type":"object","title":"Per Carat"},"sample_size":{"type":"integer","title":"Sample Size","default":0},"total_matches":{"type":"integer","title":"Total Matches","default":0},"sources":{"type":"integer","title":"Sources","default":0},"confidence":{"type":"number","title":"Confidence","default":0}},"type":"object","required":["variety","carat"],"title":"MarketEstimateResponse"},"MarketOut":{"properties":{"sold":{"anyOf":[{"$ref":"#/components/schemas/PriceBandOut"},{"type":"null"}]},"listed":{"anyOf":[{"$ref":"#/components/schemas/PriceBandOut"},{"type":"null"}]},"estimate":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Estimate"},"estimate_position":{"anyOf":[{"type":"string","enum":["below","within","above"]},{"type":"null"}],"title":"Estimate Position"}},"type":"object","title":"MarketOut"},"MarketOverviewResponse":{"properties":{"as_of":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"As Of"},"pulse":{"anyOf":[{"$ref":"#/components/schemas/PulseBlock"},{"type":"null"}]},"metal_prices":{"allOf":[{"$ref":"#/components/schemas/MetalPrices"}],"default":{}},"your_market":{"items":{"$ref":"#/components/schemas/VarietyCard"},"type":"array","title":"Your Market","default":[]},"watchlist":{"items":{"$ref":"#/components/schemas/VarietyCard"},"type":"array","title":"Watchlist","default":[]},"movers":{"allOf":[{"$ref":"#/components/schemas/app__schemas__market_v2__MoversBlock"}],"default":{"gainers":[],"losers":[]}},"news":{"items":{"$ref":"#/components/schemas/NewsItemV2"},"type":"array","title":"News","default":[]}},"type":"object","title":"MarketOverviewResponse"},"MarketReportResponse":{"properties":{"news":{"items":{"$ref":"#/components/schemas/NewsEventResponse"},"type":"array","title":"News"},"report":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Report"},"last_updated":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Updated"}},"type":"object","required":["news"],"title":"MarketReportResponse"},"MatrixResponse":{"properties":{"gemstone_type":{"type":"string","title":"Gemstone Type"},"last_updated":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Updated"},"color_grades":{"items":{"type":"string"},"type":"array","title":"Color Grades","default":[]},"weight_buckets":{"items":{"type":"string"},"type":"array","title":"Weight Buckets","default":[]},"matrix":{"items":{"$ref":"#/components/schemas/ColorRow"},"type":"array","title":"Matrix","default":[]}},"type":"object","required":["gemstone_type"],"title":"MatrixResponse"},"MessageHistoryItem":{"properties":{"id":{"type":"integer","title":"Id"},"user_message":{"type":"string","title":"User Message"},"ai_message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ai Message"},"was_accepted":{"type":"boolean","title":"Was Accepted"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","user_message","was_accepted","created_at"],"title":"MessageHistoryItem","description":"Schema for a single message in chat history"},"MetalOut":{"properties":{"metal":{"type":"string","enum":["gold","silver","platinum"],"title":"Metal"},"change_pct":{"type":"number","title":"Change Pct"},"since":{"type":"string","title":"Since"},"grams":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Grams"},"melt_now":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Melt Now"},"melt_then":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Melt Then"}},"type":"object","required":["metal","change_pct","since"],"title":"MetalOut"},"MetalPrices":{"properties":{"gold":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Gold"},"silver":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Silver"},"platinum":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Platinum"},"gold_change_7d_pct":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Gold Change 7D Pct"},"silver_change_7d_pct":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Silver Change 7D Pct"},"platinum_change_7d_pct":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Platinum Change 7D Pct"}},"type":"object","title":"MetalPrices"},"MetalSpec":{"properties":{"type":{"type":"string","title":"Type"},"color":{"type":"string","title":"Color"}},"type":"object","required":["type","color"],"title":"MetalSpec","description":"Single metal specification in jewelry"},"MilestoneIngestRequest":{"properties":{"dealer_customer_id":{"type":"string","title":"Dealer Customer Id"},"milestone":{"type":"string","title":"Milestone"},"hit_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Hit At"}},"type":"object","required":["dealer_customer_id","milestone"],"title":"MilestoneIngestRequest"},"MoverItem":{"properties":{"gemstone_id":{"type":"integer","title":"Gemstone Id"},"name":{"type":"string","title":"Name"},"current_value":{"type":"number","title":"Current Value"},"change_pct_7d":{"type":"number","title":"Change Pct 7D"},"change_abs_7d":{"type":"number","title":"Change Abs 7D"}},"type":"object","required":["gemstone_id","name","current_value","change_pct_7d","change_abs_7d"],"title":"MoverItem"},"NetworkLeadCreate":{"properties":{"professional_id":{"type":"integer","title":"Professional Id"},"gemstone_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Gemstone Id"},"lane":{"type":"string","title":"Lane","description":"appraisal | sell | insurance"},"message":{"anyOf":[{"type":"string","maxLength":1000},{"type":"null"}],"title":"Message"},"consent_share_contact":{"type":"boolean","title":"Consent Share Contact","description":"Must be literally true; the consent record."},"contact_phone":{"anyOf":[{"type":"string","maxLength":50},{"type":"null"}],"title":"Contact Phone"}},"type":"object","required":["professional_id","lane","consent_share_contact"],"title":"NetworkLeadCreate"},"NetworkLeadListRow":{"properties":{"id":{"type":"integer","title":"Id"},"professional_id":{"type":"integer","title":"Professional Id"},"professional_name":{"type":"string","title":"Professional Name"},"professional_city":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Professional City"},"gemstone_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Gemstone Id"},"gem_title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Gem Title"},"lane":{"type":"string","title":"Lane"},"status":{"type":"string","title":"Status"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","professional_id","professional_name","professional_city","gemstone_id","gem_title","lane","status","created_at"],"title":"NetworkLeadListRow"},"NetworkLeadResponse":{"properties":{"id":{"type":"integer","title":"Id"},"professional_id":{"type":"integer","title":"Professional Id"},"professional_name":{"type":"string","title":"Professional Name"},"gemstone_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Gemstone Id"},"lane":{"type":"string","title":"Lane"},"status":{"type":"string","title":"Status"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"already_requested":{"type":"boolean","title":"Already Requested","default":false},"message":{"type":"string","title":"Message","default":""}},"type":"object","required":["id","professional_id","professional_name","gemstone_id","lane","status","created_at"],"title":"NetworkLeadResponse"},"NetworkOrigin":{"properties":{"kind":{"type":"string","title":"Kind"},"country":{"type":"string","title":"Country"},"label":{"type":"string","title":"Label"}},"type":"object","required":["kind","country","label"],"title":"NetworkOrigin"},"NetworkProfessionalRow":{"properties":{"id":{"type":"integer","title":"Id"},"display_name":{"type":"string","title":"Display Name"},"business_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Business Name"},"blurb":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Blurb"},"credentials":{"items":{"type":"string"},"type":"array","title":"Credentials"},"role":{"type":"string","title":"Role"},"city":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"City"},"region_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Region Code"},"country_code":{"type":"string","title":"Country Code"},"distance_km":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Distance Km"},"lat":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Lat"},"lng":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Lng"},"claim_status":{"type":"string","title":"Claim Status"},"accepts_leads":{"type":"boolean","title":"Accepts Leads"},"phone":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Phone"},"website":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Website"},"source_attribution":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Attribution"}},"type":"object","required":["id","display_name","business_name","blurb","credentials","role","city","region_code","country_code","distance_km","claim_status","accepts_leads","phone","website","source_attribution"],"title":"NetworkProfessionalRow"},"NetworkProfessionalsResponse":{"properties":{"lane":{"type":"string","title":"Lane"},"origin":{"$ref":"#/components/schemas/NetworkOrigin"},"results":{"items":{"$ref":"#/components/schemas/NetworkProfessionalRow"},"type":"array","title":"Results"},"widened":{"type":"boolean","title":"Widened"},"national":{"items":{"$ref":"#/components/schemas/CoverageProviderResponse"},"type":"array","title":"National"},"units":{"type":"string","title":"Units"},"disclosure":{"type":"string","title":"Disclosure"}},"type":"object","required":["lane","origin","results","widened","national","units","disclosure"],"title":"NetworkProfessionalsResponse"},"NewsEventDetail":{"properties":{"id":{"type":"integer","title":"Id"},"title":{"type":"string","title":"Title"},"url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Url"},"source_name":{"type":"string","title":"Source Name"},"published_at":{"type":"string","format":"date-time","title":"Published At"},"category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category"},"sentiment_score":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Sentiment Score"},"impact_direction":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Impact Direction"},"estimated_price_impact_pct":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Estimated Price Impact Pct"},"user_facing_summary":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User Facing Summary"},"affected_species":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Affected Species"},"affected_families":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Affected Families"},"affected_countries":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Affected Countries"},"event_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Event Type"},"severity":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Severity"},"image_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Image Url"},"ai_generated":{"type":"boolean","title":"Ai Generated","default":false},"is_family_level":{"type":"boolean","title":"Is Family Level","default":false},"raw_content":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Raw Content"},"duration_estimate_months":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Duration Estimate Months"},"magnitude":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Magnitude"}},"type":"object","required":["id","title","source_name","published_at"],"title":"NewsEventDetail"},"NewsEventResponse":{"properties":{"id":{"type":"integer","title":"Id"},"title":{"type":"string","title":"Title"},"url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Url"},"source_name":{"type":"string","title":"Source Name"},"published_at":{"type":"string","format":"date-time","title":"Published At"},"category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category"},"sentiment_score":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Sentiment Score"},"impact_direction":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Impact Direction"},"estimated_price_impact_pct":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Estimated Price Impact Pct"},"user_facing_summary":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User Facing Summary"},"affected_species":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Affected Species"},"affected_families":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Affected Families"},"affected_countries":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Affected Countries"},"event_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Event Type"},"severity":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Severity"},"image_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Image Url"},"ai_generated":{"type":"boolean","title":"Ai Generated","default":false},"is_family_level":{"type":"boolean","title":"Is Family Level","default":false}},"type":"object","required":["id","title","source_name","published_at"],"title":"NewsEventResponse"},"NewsFeedResponse":{"properties":{"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"page_size":{"type":"integer","title":"Page Size"},"items":{"items":{"$ref":"#/components/schemas/NewsEventResponse"},"type":"array","title":"Items"},"family":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Family"},"family_fallback":{"type":"boolean","title":"Family Fallback","default":false}},"type":"object","required":["total","page","page_size","items"],"title":"NewsFeedResponse"},"NewsItemV2":{"properties":{"id":{"type":"integer","title":"Id"},"title":{"type":"string","title":"Title"},"url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Url"},"source_name":{"type":"string","title":"Source Name"},"published_at":{"type":"string","format":"date-time","title":"Published At"},"category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category"},"sentiment_score":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Sentiment Score"},"impact_direction":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Impact Direction"},"estimated_price_impact_pct":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Estimated Price Impact Pct"},"user_facing_summary":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User Facing Summary"},"affected_species":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Affected Species"},"affected_families":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Affected Families"},"affected_countries":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Affected Countries"},"event_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Event Type"},"severity":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Severity"},"image_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Image Url"},"ai_generated":{"type":"boolean","title":"Ai Generated","default":false},"is_family_level":{"type":"boolean","title":"Is Family Level","default":false},"outlet_count":{"type":"integer","title":"Outlet Count","default":1}},"type":"object","required":["id","title","source_name","published_at"],"title":"NewsItemV2"},"NewsletterEditionListResponse":{"properties":{"total":{"type":"integer","title":"Total"},"items":{"items":{"$ref":"#/components/schemas/NewsletterEditionResponse"},"type":"array","title":"Items"}},"type":"object","required":["total","items"],"title":"NewsletterEditionListResponse"},"NewsletterEditionResponse":{"properties":{"id":{"type":"integer","title":"Id"},"edition_number":{"type":"integer","title":"Edition Number"},"subject_line":{"type":"string","title":"Subject Line"},"preview_text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Preview Text"},"sections":{"items":{"type":"object"},"type":"array","title":"Sections"},"html_body":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Html Body"},"text_body":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Text Body"},"draft_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Draft At"},"scheduled_for":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Scheduled For"},"sent_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Sent At"},"subscriber_count":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Subscriber Count"},"open_count":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Open Count"},"click_count":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Click Count"},"unsubscribe_count":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Unsubscribe Count"},"beehiiv_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Beehiiv Id"},"status":{"type":"string","title":"Status"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","edition_number","subject_line","sections","status","created_at"],"title":"NewsletterEditionResponse"},"NewsletterStats":{"properties":{"total_subscribers":{"type":"integer","title":"Total Subscribers"},"active_subscribers":{"type":"integer","title":"Active Subscribers"},"unsubscribed":{"type":"integer","title":"Unsubscribed"},"new_this_week":{"type":"integer","title":"New This Week"},"avg_open_rate_last_5":{"type":"number","title":"Avg Open Rate Last 5"},"avg_click_rate_last_5":{"type":"number","title":"Avg Click Rate Last 5"},"by_source":{"additionalProperties":{"type":"integer"},"type":"object","title":"By Source"},"by_lifecycle_stage":{"additionalProperties":{"type":"integer"},"type":"object","title":"By Lifecycle Stage"}},"type":"object","required":["total_subscribers","active_subscribers","unsubscribed","new_this_week","avg_open_rate_last_5","avg_click_rate_last_5","by_source","by_lifecycle_stage"],"title":"NewsletterStats"},"NotificationFeedResponse":{"properties":{"items":{"items":{"$ref":"#/components/schemas/NotificationItem"},"type":"array","title":"Items"},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Cursor"},"unread_count":{"type":"integer","title":"Unread Count"}},"type":"object","required":["items","unread_count"],"title":"NotificationFeedResponse"},"NotificationItem":{"properties":{"id":{"type":"integer","title":"Id"},"type":{"type":"string","title":"Type"},"title":{"type":"string","title":"Title"},"body":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Body"},"data":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Data"},"deep_link":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Deep Link"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"read_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Read At"}},"type":"object","required":["id","type","title","created_at"],"title":"NotificationItem","description":"One inbox row as the app sees it.\n\n`data` and `deep_link` are both optional and additive: older app builds\nignore them, newer ones use deep_link for routing and fall back to data."},"NotificationPrefsRequest":{"properties":{"push":{"type":"boolean","title":"Push"},"email":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Email"},"sms":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Sms"}},"type":"object","required":["push"],"title":"NotificationPrefsRequest","description":"Request to update a user's notification preferences.\n\nOnly `push` is enforced server-side (gates push sends); `email`/`sms` are\naccepted for forward-compatibility and not yet wired to a send path.","example":{"email":false,"push":true,"sms":false}},"OTPResponse":{"properties":{"message":{"type":"string","title":"Message"},"mobile_number":{"type":"string","title":"Mobile Number"},"phone_country_code":{"type":"string","title":"Phone Country Code"},"expires_in_minutes":{"type":"integer","title":"Expires In Minutes"},"remaining_attempts":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Remaining Attempts"}},"type":"object","required":["message","mobile_number","phone_country_code","expires_in_minutes"],"title":"OTPResponse"},"OnboardingStats":{"properties":{"active":{"type":"integer","title":"Active"},"completed":{"type":"integer","title":"Completed"},"total":{"type":"integer","title":"Total"},"high_risk":{"type":"integer","title":"High Risk"},"medium_risk":{"type":"integer","title":"Medium Risk"},"touchpoints_pending":{"type":"integer","title":"Touchpoints Pending"},"touchpoints_sent_today":{"type":"integer","title":"Touchpoints Sent Today"},"avg_days_to_activation":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Avg Days To Activation"}},"type":"object","required":["active","completed","total","high_risk","medium_risk","touchpoints_pending","touchpoints_sent_today"],"title":"OnboardingStats"},"OpenQuestionOut":{"properties":{"about":{"type":"string","title":"About"},"text":{"type":"string","title":"Text"},"settle":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Settle"},"species":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Species"},"scan_said":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Scan Said"},"ids":{"items":{"type":"integer"},"type":"array","title":"Ids","default":[]}},"type":"object","required":["about","text"],"title":"OpenQuestionOut"},"OriginEstimate":{"properties":{"likely_origin":{"type":"string","title":"Likely Origin","default":"Unknown"},"confidence":{"type":"integer","title":"Confidence","default":0},"basis":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Basis"}},"type":"object","title":"OriginEstimate","description":"AI-estimated geographic origin with confidence"},"OriginEstimateV2":{"properties":{"likely_origin":{"type":"string","title":"Likely Origin","default":"Unknown"},"confidence":{"type":"integer","maximum":100.0,"minimum":0.0,"title":"Confidence","default":0},"basis":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Basis"}},"type":"object","title":"OriginEstimateV2"},"OutboundStats":{"properties":{"sends_today":{"type":"integer","title":"Sends Today"},"sends_this_week":{"type":"integer","title":"Sends This Week"},"open_rate_7d":{"type":"number","title":"Open Rate 7D"},"reply_rate_7d":{"type":"number","title":"Reply Rate 7D"},"positive_reply_rate_7d":{"type":"number","title":"Positive Reply Rate 7D"},"demos_booked_7d":{"type":"integer","title":"Demos Booked 7D"},"per_sequence":{"additionalProperties":{"type":"object"},"type":"object","title":"Per Sequence"},"per_mailbox_health":{"additionalProperties":{"type":"object"},"type":"object","title":"Per Mailbox Health"},"pending_review":{"type":"integer","title":"Pending Review"}},"type":"object","required":["sends_today","sends_this_week","open_rate_7d","reply_rate_7d","positive_reply_rate_7d","demos_booked_7d","per_sequence","per_mailbox_health","pending_review"],"title":"OutboundStats"},"PersonOut":{"properties":{"id":{"type":"integer","title":"Id"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"role":{"type":"string","enum":["from","for"],"title":"Role"},"relation":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Relation"},"text":{"type":"string","title":"Text"},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updated At"}},"type":"object","required":["id","role","text"],"title":"PersonOut"},"PieceOut":{"properties":{"id":{"type":"integer","title":"Id"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"image_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Image Url"},"species":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Species"},"jewelry_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Jewelry Type"},"metal":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Metal"},"carat":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Carat"}},"type":"object","required":["id"],"title":"PieceOut"},"PieceStateOut":{"properties":{"gem_id":{"type":"integer","title":"Gem Id"},"capabilities":{"$ref":"#/components/schemas/CapabilitiesOut"},"question":{"anyOf":[{"$ref":"#/components/schemas/QuestionOut"},{"type":"null"}]},"market":{"anyOf":[{"$ref":"#/components/schemas/MarketOut"},{"type":"null"}]},"metal":{"anyOf":[{"$ref":"#/components/schemas/MetalOut"},{"type":"null"}]},"community":{"anyOf":[{"$ref":"#/components/schemas/CommunityOut"},{"type":"null"}]},"reminders":{"items":{"$ref":"#/components/schemas/ReminderOut"},"type":"array","title":"Reminders"},"findings":{"items":{"$ref":"#/components/schemas/FindingOut"},"type":"array","title":"Findings"}},"type":"object","required":["gem_id","capabilities","reminders","findings"],"title":"PieceStateOut"},"PieceTypeContentResponse":{"properties":{"piece_type":{"type":"string","title":"Piece Type","description":"Canonical key, e.g. 'wedding_band'"},"subject":{"type":"string","title":"Subject","description":"Heading subject, e.g. 'Wedding Bands'"},"history_lore":{"type":"string","title":"History Lore"},"cultural_significance":{"type":"string","title":"Cultural Significance"},"buyers_guide":{"type":"string","title":"Buyers Guide"},"content_version":{"type":"integer","title":"Content Version"}},"type":"object","required":["piece_type","subject","history_lore","cultural_significance","buyers_guide","content_version"],"title":"PieceTypeContentResponse","description":"Field names match SpeciesContentResponse so the app renders both alike."},"PlanCreate":{"properties":{"name":{"type":"string","maxLength":100,"minLength":1,"title":"Name"},"display_name":{"type":"string","maxLength":150,"minLength":1,"title":"Display Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"features":{"anyOf":[{"additionalProperties":{"items":{"type":"object"},"type":"array"},"type":"object"},{"type":"null"}],"title":"Features","default":{}},"is_scan_unlimited":{"type":"boolean","title":"Is Scan Unlimited","default":false},"scan_limit":{"anyOf":[{"type":"integer","minimum":1.0},{"type":"null"}],"title":"Scan Limit"},"is_collection_unlimited":{"type":"boolean","title":"Is Collection Unlimited","default":false},"collection_size_limit":{"anyOf":[{"type":"integer","minimum":1.0},{"type":"null"}],"title":"Collection Size Limit"},"is_visible":{"type":"boolean","title":"Is Visible","default":true},"sort_order":{"type":"integer","title":"Sort Order","default":0}},"type":"object","required":["name","display_name"],"title":"PlanCreate","description":"Schema for creating a new plan"},"PlanOptionCreate":{"properties":{"billing_period":{"type":"string","pattern":"^(monthly|yearly|quarterly|weekly)$","title":"Billing Period"},"billing_interval_count":{"type":"integer","minimum":1.0,"title":"Billing Interval Count","default":1},"price":{"anyOf":[{"type":"number","minimum":0.0},{"type":"string"}],"title":"Price"},"currency":{"type":"string","pattern":"^[A-Z]{3}$","title":"Currency","default":"USD"},"display_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Display Name"},"savings_text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Savings Text"},"trial_period_days":{"type":"integer","minimum":0.0,"title":"Trial Period Days","default":0},"gateway_data":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Gateway Data"}},"type":"object","required":["billing_period","price"],"title":"PlanOptionCreate","description":"Schema for creating a plan option"},"PlanOptionResponse":{"properties":{"id":{"type":"integer","title":"Id"},"plan_id":{"type":"integer","title":"Plan Id"},"billing_period":{"type":"string","title":"Billing Period"},"billing_interval_count":{"type":"integer","title":"Billing Interval Count"},"price":{"type":"string","title":"Price"},"currency":{"type":"string","title":"Currency"},"display_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Display Name"},"savings_text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Savings Text"},"trial_period_days":{"type":"integer","title":"Trial Period Days"},"gateway_data":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Gateway Data"},"is_active":{"type":"boolean","title":"Is Active"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","plan_id","billing_period","billing_interval_count","price","currency","display_name","savings_text","trial_period_days","gateway_data","is_active","created_at","updated_at"],"title":"PlanOptionResponse","description":"Plan option response"},"PlanOptionUpdate":{"properties":{"billing_period":{"anyOf":[{"type":"string","pattern":"^(monthly|yearly|quarterly|weekly)$"},{"type":"null"}],"title":"Billing Period"},"billing_interval_count":{"anyOf":[{"type":"integer","minimum":1.0},{"type":"null"}],"title":"Billing Interval Count"},"price":{"anyOf":[{"type":"number"},{"type":"string"},{"type":"null"}],"title":"Price"},"currency":{"anyOf":[{"type":"string","pattern":"^[A-Z]{3}$"},{"type":"null"}],"title":"Currency"},"display_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Display Name"},"savings_text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Savings Text"},"trial_period_days":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Trial Period Days"},"is_active":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Active"},"gateway_data":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Gateway Data"}},"type":"object","title":"PlanOptionUpdate","description":"Schema for updating a plan option"},"PlanResponse":{"properties":{"id":{"type":"integer","title":"Id"},"name":{"type":"string","title":"Name"},"display_name":{"type":"string","title":"Display Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"features":{"anyOf":[{"additionalProperties":{"items":{"type":"object"},"type":"array"},"type":"object"},{"type":"null"}],"title":"Features"},"is_scan_unlimited":{"type":"boolean","title":"Is Scan Unlimited"},"scan_limit":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Scan Limit"},"is_collection_unlimited":{"type":"boolean","title":"Is Collection Unlimited"},"collection_size_limit":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Collection Size Limit"},"is_active":{"type":"boolean","title":"Is Active"},"is_visible":{"type":"boolean","title":"Is Visible"},"sort_order":{"type":"integer","title":"Sort Order"},"plan_options":{"items":{"$ref":"#/components/schemas/PlanOptionResponse"},"type":"array","title":"Plan Options","default":[]},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","name","display_name","description","features","is_scan_unlimited","scan_limit","is_collection_unlimited","collection_size_limit","is_active","is_visible","sort_order","created_at","updated_at"],"title":"PlanResponse","description":"Plan response with options"},"PlanUpdate":{"properties":{"name":{"anyOf":[{"type":"string","maxLength":100,"minLength":1},{"type":"null"}],"title":"Name"},"display_name":{"anyOf":[{"type":"string","maxLength":150,"minLength":1},{"type":"null"}],"title":"Display Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"features":{"anyOf":[{"additionalProperties":{"items":{"type":"object"},"type":"array"},"type":"object"},{"type":"null"}],"title":"Features"},"is_scan_unlimited":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Scan Unlimited"},"scan_limit":{"anyOf":[{"type":"integer","minimum":1.0},{"type":"null"}],"title":"Scan Limit"},"is_collection_unlimited":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Collection Unlimited"},"collection_size_limit":{"anyOf":[{"type":"integer","minimum":1.0},{"type":"null"}],"title":"Collection Size Limit"},"is_active":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Active"},"is_visible":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Visible"},"sort_order":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Sort Order"}},"type":"object","title":"PlanUpdate","description":"Schema for updating a plan"},"PortfolioEvent":{"properties":{"date":{"type":"string","title":"Date"},"type":{"type":"string","title":"Type"},"label":{"type":"string","title":"Label"},"value":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Value"},"gemstone_id":{"type":"integer","title":"Gemstone Id"}},"type":"object","required":["date","type","label","gemstone_id"],"title":"PortfolioEvent"},"PortfolioEventsResponse":{"properties":{"events":{"items":{"$ref":"#/components/schemas/PortfolioEvent"},"type":"array","title":"Events"}},"type":"object","required":["events"],"title":"PortfolioEventsResponse"},"PortfolioHistoryPoint":{"properties":{"date":{"type":"string","title":"Date"},"total_value":{"type":"number","title":"Total Value"}},"type":"object","required":["date","total_value"],"title":"PortfolioHistoryPoint","description":"One daily portfolio snapshot (LNK-DRIFT)."},"PortfolioHistoryResponse":{"properties":{"points":{"items":{"$ref":"#/components/schemas/PortfolioHistoryPoint"},"type":"array","title":"Points"},"current_value":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Current Value"},"change_abs_7d":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Change Abs 7D"},"change_pct_7d":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Change Pct 7D"},"change_pct_30d":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Change Pct 30D"}},"type":"object","required":["points"],"title":"PortfolioHistoryResponse","description":"Portfolio value time series from portfolio_snapshots (LNK-DRIFT).\n\nChange fields are null until enough snapshot history exists (e.g. no\nsnapshot ≥7 days old yet → change_*_7d are null)."},"PortfolioSummaryResponse":{"properties":{"total_gems":{"type":"integer","title":"Total Gems"},"valued_gems":{"type":"integer","title":"Valued Gems"},"currency":{"type":"string","title":"Currency","default":"USD"},"total_value":{"type":"number","title":"Total Value"},"total_value_min":{"type":"number","title":"Total Value Min"},"total_value_max":{"type":"number","title":"Total Value Max"}},"type":"object","required":["total_gems","valued_gems","total_value","total_value_min","total_value_max"],"title":"PortfolioSummaryResponse","description":"GET /gems/portfolio response.\n\nAdditive-only contract: feat/2026-06-09-portfolio-drift-alerts extends\nthis schema — never rename/remove fields, only add."},"PositionGem":{"properties":{"id":{"type":"integer","title":"Id"},"name":{"type":"string","title":"Name"},"image_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Image Url"},"estimated_value":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Estimated Value"}},"type":"object","required":["id","name"],"title":"PositionGem"},"PossibleSamePiece":{"properties":{"gemstone_id":{"type":"integer","title":"Gemstone Id"},"minutes_ago":{"type":"integer","title":"Minutes Ago"},"species":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Species"},"best":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Best"},"range_min":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Range Min"},"range_max":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Range Max"},"image_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Image Url"}},"type":"object","required":["gemstone_id","minutes_ago"],"title":"PossibleSamePiece","description":"[LNK-RESCAN] A recent scan that looks like this piece but read a very\ndifferent value. The client asks the user whether to combine the two."},"PreferenceOut":{"properties":{"group":{"type":"string","enum":["likes","dislikes","interests","context","practical","fewer"],"title":"Group"},"text":{"type":"string","title":"Text"},"quote":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Quote"},"ids":{"items":{"type":"integer"},"type":"array","title":"Ids"},"until":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Until"}},"type":"object","required":["group","text","ids"],"title":"PreferenceOut"},"PreferencesOut":{"properties":{"items":{"items":{"$ref":"#/components/schemas/PreferenceOut"},"type":"array","title":"Items"}},"type":"object","required":["items"],"title":"PreferencesOut"},"PriceBandOut":{"properties":{"count":{"type":"integer","title":"Count"},"low":{"type":"integer","title":"Low"},"high":{"type":"integer","title":"High"}},"type":"object","required":["count","low","high"],"title":"PriceBandOut"},"PriceComponent":{"properties":{"currency":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Currency"},"exposure":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Exposure"},"component_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Component Id"},"basis":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Basis"},"as_of":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"As Of"},"evidence_ids":{"items":{"type":"string"},"type":"array","title":"Evidence Ids"},"movement_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Movement Status"},"change_amount":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Change Amount"},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason"},"label":{"type":"string","title":"Label"},"amount":{"type":"number","minimum":0.0,"title":"Amount"},"note":{"type":"string","title":"Note"}},"type":"object","required":["label","amount","note"],"title":"PriceComponent"},"PriceEstimate":{"properties":{"amount":{"anyOf":[{"type":"number","minimum":0.0},{"type":"null"}],"title":"Amount"},"basis":{"type":"string","title":"Basis"},"source":{"type":"string","enum":["model","asking_listings","completed_sales","unavailable"],"title":"Source","default":"unavailable"},"evidence_count":{"type":"integer","title":"Evidence Count","default":0},"explanation":{"type":"string","title":"Explanation","default":""},"gross_amount":{"anyOf":[{"type":"number","minimum":0.0},{"type":"null"}],"title":"Gross Amount"},"fee_rate":{"anyOf":[{"type":"number","exclusiveMaximum":1.0,"minimum":0.0},{"type":"null"}],"title":"Fee Rate"},"fee_fixed":{"anyOf":[{"type":"number","minimum":0.0},{"type":"null"}],"title":"Fee Fixed"},"fee_note":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Fee Note"},"status":{"type":"string","enum":["available","pending","unsupported"],"title":"Status","default":"unsupported"},"range_min":{"anyOf":[{"type":"number","minimum":0.0},{"type":"null"}],"title":"Range Min"},"range_max":{"anyOf":[{"type":"number","minimum":0.0},{"type":"null"}],"title":"Range Max"},"range_kind":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Range Kind"},"method":{"type":"string","title":"Method","default":"legacy_unspecified"},"method_version":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Method Version"},"as_of":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"As Of"},"currency":{"type":"string","title":"Currency","default":"USD"},"market":{"type":"string","title":"Market","default":"consumer"},"condition":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Condition"},"subject_version":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Subject Version"},"evidence_ids":{"items":{"type":"string"},"type":"array","title":"Evidence Ids"},"freshness":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Freshness"},"calculation_plan":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Calculation Plan"},"components":{"items":{"$ref":"#/components/schemas/PriceComponent"},"type":"array","title":"Components"}},"type":"object","required":["basis"],"title":"PriceEstimate"},"PriceFeedbackRequest":{"properties":{"verdict":{"type":"string","enum":["too_low","about_right","too_high"],"title":"Verdict"},"user_estimate":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"User Estimate"}},"type":"object","required":["verdict"],"title":"PriceFeedbackRequest","description":"Body for POST /api/v1/gems/{gem_id}/price-feedback."},"PriceFeedbackResponse":{"properties":{"id":{"type":"integer","title":"Id"},"gemstone_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Gemstone Id"},"species":{"type":"string","title":"Species"},"user_verdict":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User Verdict"},"user_estimate":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"User Estimate"},"estimated_price_min":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Estimated Price Min"},"estimated_price_max":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Estimated Price Max"},"market_price":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Market Price"}},"type":"object","required":["id","species"],"title":"PriceFeedbackResponse","description":"The saved scan_price_feedback row."},"PricingDetails":{"properties":{"min":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Min"},"avg":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Avg"},"max":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Max"},"yoy_change_percent":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Yoy Change Percent"},"p10":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"P10"},"p25":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"P25"},"p50":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"P50"},"p75":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"P75"},"p90":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"P90"},"p95":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"P95"},"median_k":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Median K","description":"Median price in $K (p50 / 1000)"},"computed_yoy_percent":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Computed Yoy Percent","description":"Computed YoY % change vs. 2024 avg"},"floor_k":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Floor K","description":"Floor price in $K (min or p10 / 1000)"},"premium_k":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Premium K","description":"Premium price in $K (p75 / 1000)"},"distribution_params":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Distribution Params","description":"Params for bell curve: mean ($K), std ($K), skew hint"}},"type":"object","title":"PricingDetails"},"PricingResult":{"properties":{"stage":{"type":"string","enum":["initial","researched"],"title":"Stage","default":"researched"},"display_assumption":{"anyOf":[{"type":"string","maxLength":140},{"type":"null"}],"title":"Display Assumption"},"version":{"type":"string","title":"Version"},"status":{"type":"string","enum":["pending","ready","partial","failed","deferred"],"title":"Status"},"subject_key":{"type":"string","title":"Subject Key"},"currency":{"type":"string","title":"Currency","default":"USD"},"priced_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Priced At"},"subject":{"type":"object","title":"Subject"},"purchase":{"$ref":"#/components/schemas/PriceEstimate"},"resale":{"$ref":"#/components/schemas/PriceEstimate"},"components":{"items":{"$ref":"#/components/schemas/PriceComponent"},"type":"array","title":"Components"},"evidence":{"items":{"type":"object"},"type":"array","title":"Evidence"},"assumptions":{"items":{"type":"string"},"type":"array","title":"Assumptions"},"requested_inputs":{"items":{"type":"string"},"type":"array","title":"Requested Inputs"},"requested_attributes":{"items":{"type":"string"},"type":"array","title":"Requested Attributes"},"insurance_note":{"type":"string","title":"Insurance Note","default":"For insurance, confirm replacement value with your insurer or an appraiser."},"valuation_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Valuation Id"},"previous_valuation":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Previous Valuation"}},"type":"object","required":["version","status","subject_key"],"title":"PricingResult"},"ProfessionalClickRequest":{"properties":{"lane":{"type":"string","title":"Lane","description":"appraisal | sell | insurance"},"action":{"type":"string","title":"Action","description":"call | website | view","default":"website"},"gemstone_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Gemstone Id"}},"type":"object","required":["lane"],"title":"ProfessionalClickRequest"},"PromoCodeResponse":{"properties":{"id":{"type":"integer","title":"Id"},"code":{"type":"string","title":"Code"},"campaign":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Campaign"},"note":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Note"},"premium_days":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Premium Days"},"bonus_scans":{"type":"integer","title":"Bonus Scans"},"max_redemptions":{"type":"integer","title":"Max Redemptions"},"redemption_count":{"type":"integer","title":"Redemption Count"},"restricted_email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Restricted Email"},"expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Expires At"},"is_active":{"type":"boolean","title":"Is Active"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","code","bonus_scans","max_redemptions","redemption_count","is_active","created_at"],"title":"PromoCodeResponse"},"PromoGrantRequest":{"properties":{"email":{"type":"string","title":"Email","description":"Address to comp"},"premium_days":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Premium Days","description":"null = lifetime","default":365},"note":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Note"},"campaign":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Campaign"}},"type":"object","required":["email"],"title":"PromoGrantRequest"},"PromoGrantResponse":{"properties":{"code":{"type":"string","title":"Code"},"email":{"type":"string","title":"Email"},"applied":{"type":"boolean","title":"Applied"},"user_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"User Id"},"premium_until":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Premium Until"},"message":{"type":"string","title":"Message"}},"type":"object","required":["code","email","applied","message"],"title":"PromoGrantResponse"},"PromoMintRequest":{"properties":{"count":{"type":"integer","maximum":500.0,"minimum":1.0,"title":"Count","description":"How many codes to mint","default":1},"premium_days":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Premium Days","description":"Days of premium granted. null = lifetime.","default":365},"bonus_scans":{"type":"integer","minimum":0.0,"title":"Bonus Scans","default":0},"campaign":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Campaign","description":"e.g. \"outreach-jul\""},"note":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Note","description":"Who it went to / why"},"max_redemptions":{"type":"integer","minimum":0.0,"title":"Max Redemptions","description":"0 = unlimited redemptions","default":1},"restricted_email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Restricted Email","description":"Lock the code to one address; it auto-applies when they sign up"},"expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Expires At","description":"Code unusable after this"},"code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Code","description":"Mint one specific vanity code"},"prefix":{"type":"string","title":"Prefix","description":"Prefix for generated codes","default":"GEM"}},"type":"object","title":"PromoMintRequest"},"PromoMintResponse":{"properties":{"created":{"type":"integer","title":"Created"},"codes":{"items":{"$ref":"#/components/schemas/PromoCodeResponse"},"type":"array","title":"Codes"}},"type":"object","required":["created","codes"],"title":"PromoMintResponse"},"PromoPreviewResponse":{"properties":{"code":{"type":"string","title":"Code"},"valid":{"type":"boolean","title":"Valid"},"premium_days":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Premium Days"},"bonus_scans":{"type":"integer","title":"Bonus Scans","default":0},"requires_matching_email":{"type":"boolean","title":"Requires Matching Email","default":false},"message":{"type":"string","title":"Message"}},"type":"object","required":["code","valid","message"],"title":"PromoPreviewResponse"},"PromoRedeemRequest":{"properties":{"code":{"type":"string","title":"Code","description":"Promo code, case-insensitive (e.g. GEM-K4M2XP)"}},"type":"object","required":["code"],"title":"PromoRedeemRequest"},"PromoRedeemResponse":{"properties":{"granted":{"type":"boolean","title":"Granted"},"code":{"type":"string","title":"Code"},"premium_until":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Premium Until"},"is_lifetime":{"type":"boolean","title":"Is Lifetime","default":false},"bonus_scans":{"type":"integer","title":"Bonus Scans","default":0},"message":{"type":"string","title":"Message"}},"type":"object","required":["granted","code","message"],"title":"PromoRedeemResponse"},"ProspectCreate":{"properties":{"company_name":{"type":"string","title":"Company Name"},"website_domain":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Website Domain"},"primary_contact_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Primary Contact Name"},"primary_contact_email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Primary Contact Email"},"primary_contact_phone":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Primary Contact Phone"},"linkedin_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Linkedin Url"},"business_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Business Type"},"location_city":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Location City"},"location_country":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Location Country"},"location_lat":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Location Lat"},"location_lng":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Location Lng"},"stone_focus":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Stone Focus"},"inventory_size_estimate":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Inventory Size Estimate"},"agta_member":{"type":"boolean","title":"Agta Member","default":false},"jck_exhibitor":{"type":"boolean","title":"Jck Exhibitor","default":false},"tucson_history":{"anyOf":[{"items":{"type":"object"},"type":"array"},{"type":"null"}],"title":"Tucson History"},"instagram_handle":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Instagram Handle"},"instagram_followers":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Instagram Followers"},"instagram_posting_frequency":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Instagram Posting Frequency"},"tags":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Tags"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"}},"type":"object","required":["company_name"],"title":"ProspectCreate"},"ProspectEnrichRequest":{"properties":{"sources":{"items":{"type":"string"},"type":"array","title":"Sources"},"force_refresh":{"type":"boolean","title":"Force Refresh","default":false}},"type":"object","title":"ProspectEnrichRequest"},"ProspectImportResult":{"properties":{"import_id":{"type":"integer","title":"Import Id"},"source":{"type":"string","title":"Source"},"row_count":{"type":"integer","title":"Row Count"},"success_count":{"type":"integer","title":"Success Count"},"skip_count":{"type":"integer","title":"Skip Count"},"error_count":{"type":"integer","title":"Error Count"},"errors":{"anyOf":[{"items":{"type":"object"},"type":"array"},{"type":"null"}],"title":"Errors"}},"type":"object","required":["import_id","source","row_count","success_count","skip_count","error_count"],"title":"ProspectImportResult"},"ProspectListResponse":{"properties":{"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"page_size":{"type":"integer","title":"Page Size"},"items":{"items":{"$ref":"#/components/schemas/ProspectResponse"},"type":"array","title":"Items"}},"type":"object","required":["total","page","page_size","items"],"title":"ProspectListResponse"},"ProspectResponse":{"properties":{"company_name":{"type":"string","title":"Company Name"},"website_domain":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Website Domain"},"primary_contact_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Primary Contact Name"},"primary_contact_email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Primary Contact Email"},"primary_contact_phone":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Primary Contact Phone"},"linkedin_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Linkedin Url"},"business_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Business Type"},"location_city":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Location City"},"location_country":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Location Country"},"location_lat":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Location Lat"},"location_lng":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Location Lng"},"stone_focus":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Stone Focus"},"inventory_size_estimate":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Inventory Size Estimate"},"agta_member":{"type":"boolean","title":"Agta Member","default":false},"jck_exhibitor":{"type":"boolean","title":"Jck Exhibitor","default":false},"tucson_history":{"anyOf":[{"items":{"type":"object"},"type":"array"},{"type":"null"}],"title":"Tucson History"},"instagram_handle":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Instagram Handle"},"instagram_followers":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Instagram Followers"},"instagram_posting_frequency":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Instagram Posting Frequency"},"tags":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Tags"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"},"id":{"type":"integer","title":"Id"},"relationship_stage":{"type":"string","title":"Relationship Stage"},"last_touch_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Touch At"},"next_touch_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Next Touch At"},"personalization_hooks":{"anyOf":[{"items":{"type":"object"},"type":"array"},{"type":"null"}],"title":"Personalization Hooks"},"deal_value_estimate":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Deal Value Estimate"},"expected_close_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Expected Close Date"},"champion_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Champion Name"},"case_study_eligible":{"type":"boolean","title":"Case Study Eligible","default":false},"apollo_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Apollo Id"},"attio_person_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Attio Person Id"},"suppressed":{"type":"boolean","title":"Suppressed","default":false},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["company_name","id","relationship_stage","created_at","updated_at"],"title":"ProspectResponse"},"ProspectSignalCreate":{"properties":{"signal_type":{"type":"string","title":"Signal Type"},"content":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Content"},"source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source"},"source_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Url"},"signal_metadata":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Signal Metadata"}},"type":"object","required":["signal_type"],"title":"ProspectSignalCreate"},"ProspectSignalResponse":{"properties":{"id":{"type":"integer","title":"Id"},"prospect_id":{"type":"integer","title":"Prospect Id"},"signal_type":{"type":"string","title":"Signal Type"},"content":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Content"},"source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source"},"source_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Url"},"observed_at":{"type":"string","format":"date-time","title":"Observed At"},"signal_metadata":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Signal Metadata"}},"type":"object","required":["id","prospect_id","signal_type","observed_at"],"title":"ProspectSignalResponse"},"ProspectStats":{"properties":{"total":{"type":"integer","title":"Total"},"by_stage":{"additionalProperties":{"type":"integer"},"type":"object","title":"By Stage"},"by_business_type":{"additionalProperties":{"type":"integer"},"type":"object","title":"By Business Type"},"by_agta":{"additionalProperties":{"type":"integer"},"type":"object","title":"By Agta"},"by_jck":{"additionalProperties":{"type":"integer"},"type":"object","title":"By Jck"},"upcoming_touches_next_7d":{"type":"integer","title":"Upcoming Touches Next 7D"},"touches_overdue":{"type":"integer","title":"Touches Overdue"},"suppressed":{"type":"integer","title":"Suppressed"}},"type":"object","required":["total","by_stage","by_business_type","by_agta","by_jck","upcoming_touches_next_7d","touches_overdue","suppressed"],"title":"ProspectStats"},"ProspectUpdate":{"properties":{"company_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Company Name"},"website_domain":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Website Domain"},"primary_contact_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Primary Contact Name"},"primary_contact_email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Primary Contact Email"},"primary_contact_phone":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Primary Contact Phone"},"linkedin_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Linkedin Url"},"business_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Business Type"},"location_city":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Location City"},"location_country":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Location Country"},"stone_focus":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Stone Focus"},"inventory_size_estimate":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Inventory Size Estimate"},"agta_member":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Agta Member"},"jck_exhibitor":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Jck Exhibitor"},"tucson_history":{"anyOf":[{"items":{"type":"object"},"type":"array"},{"type":"null"}],"title":"Tucson History"},"instagram_handle":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Instagram Handle"},"instagram_followers":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Instagram Followers"},"relationship_stage":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Relationship Stage"},"next_touch_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Next Touch At"},"deal_value_estimate":{"anyOf":[{"type":"number"},{"type":"string"},{"type":"null"}],"title":"Deal Value Estimate"},"expected_close_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Expected Close Date"},"champion_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Champion Name"},"blocker_notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Blocker Notes"},"case_study_eligible":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Case Study Eligible"},"tags":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Tags"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"},"suppressed":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Suppressed"},"suppression_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Suppression Reason"}},"type":"object","title":"ProspectUpdate"},"ProviderClickRequest":{"properties":{"kind":{"type":"string","title":"Kind","description":"coverage | appraisal"},"gemstone_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Gemstone Id"}},"type":"object","required":["kind"],"title":"ProviderClickRequest"},"PulseBlock":{"properties":{"headline":{"type":"string","title":"Headline"},"body":{"type":"string","title":"Body"},"generated_at":{"type":"string","format":"date-time","title":"Generated At"}},"type":"object","required":["headline","body","generated_at"],"title":"PulseBlock"},"PushTokenRequest":{"properties":{"push_token":{"type":"string","title":"Push Token"}},"type":"object","required":["push_token"],"title":"PushTokenRequest","description":"Request to register/update push notification token","example":{"push_token":"ExponentPushToken[xxxxxxxxxxxxxxxxxxxxxx]"}},"QuestionOut":{"properties":{"kind":{"const":"confirm_identity","title":"Kind"},"title":{"type":"string","title":"Title"},"body":{"type":"string","title":"Body"},"species":{"type":"string","title":"Species"},"alternatives":{"items":{"type":"string"},"type":"array","title":"Alternatives","default":[]}},"type":"object","required":["kind","title","body","species"],"title":"QuestionOut"},"QuickSubscriptionStatusResponse":{"properties":{"plan_type":{"type":"string","title":"Plan Type","description":"'free' or 'premium'"},"is_active":{"type":"boolean","title":"Is Active","description":"Is subscription active?"},"is_premium":{"type":"boolean","title":"Is Premium","description":"True if user has active premium subscription, False otherwise"},"scans_remaining":{"anyOf":[{"type":"string"},{"type":"integer"}],"title":"Scans Remaining","description":"'unlimited' or number"},"collection_slots_remaining":{"anyOf":[{"type":"string"},{"type":"integer"}],"title":"Collection Slots Remaining","description":"'unlimited' or number (10 - current_count)"},"scans_limit":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Scans Limit","description":"Monthly scan limit (null if unlimited)"},"collection_limit":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Collection Limit","description":"Collection size limit (null if unlimited)"},"scan_tier":{"anyOf":[{"$ref":"#/components/schemas/ScanTierQuota"},{"type":"null"}],"description":"Monthly allowance on a capped paid tier"}},"type":"object","required":["plan_type","is_active","is_premium","scans_remaining","collection_slots_remaining"],"title":"QuickSubscriptionStatusResponse","description":"Quick subscription status check - lightweight response for UI state management.\n\nUse this API when you need to quickly check:\n- Is user Free or Premium?\n- Is subscription active?\n- How many scans/gems remaining?\n\nPerfect for: Headers, dashboards, quick checks before actions","example":{"collection_limit":10,"collection_slots_remaining":7,"is_active":true,"is_premium":false,"plan_type":"free","scans_limit":5,"scans_remaining":3}},"RatingEligibilityResponse":{"properties":{"can_rate":{"type":"boolean","title":"Can Rate"},"is_bonus_applicable":{"type":"boolean","title":"Is Bonus Applicable"},"bonus_scans":{"type":"integer","title":"Bonus Scans"},"reason":{"type":"string","title":"Reason"}},"type":"object","required":["can_rate","is_bonus_applicable","bonus_scans","reason"],"title":"RatingEligibilityResponse","description":"Response for rating eligibility check"},"RcSyncResponse":{"properties":{"ok":{"type":"boolean","title":"Ok"},"message":{"type":"string","title":"Message"},"user_id":{"type":"integer","title":"User Id"},"status":{"type":"string","title":"Status"},"entitlement_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Entitlement Id"},"product_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Product Id"},"store":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Store"},"current_period_end":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Current Period End"},"cancel_at_period_end":{"type":"boolean","title":"Cancel At Period End","default":false}},"type":"object","required":["ok","message","user_id","status"],"title":"RcSyncResponse"},"ReconciliationTrace":{"properties":{"action":{"anyOf":[{"type":"string","enum":["override","low_confidence","same_item_divergent","same_item_species_conflict","none"]},{"type":"null"}],"title":"Action"},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason"},"from_species":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"From Species"},"to_species":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"To Species"},"same_item_ids":{"items":{"type":"integer"},"type":"array","title":"Same Item Ids"}},"type":"object","title":"ReconciliationTrace","description":"Trace of the scan-consistency layer (LNK-SCANFIX). Present when an\noutlier was corrected against the user's same-item recent scans, or a\nlow-confidence value was gated. Lenient by design — telemetry, never fails\na scan."},"RecordOut":{"properties":{"gem_id":{"type":"integer","title":"Gem Id"},"stories":{"items":{"$ref":"#/components/schemas/StoryOut"},"type":"array","title":"Stories"},"people":{"items":{"$ref":"#/components/schemas/PersonOut"},"type":"array","title":"People"},"suggestions":{"items":{"$ref":"#/components/schemas/SuggestionOut"},"type":"array","title":"Suggestions"},"on_schedule":{"type":"boolean","title":"On Schedule"},"links":{"items":{"$ref":"#/components/schemas/LinkOut"},"type":"array","title":"Links"},"card_facts":{"items":{"$ref":"#/components/schemas/CardFactOut"},"type":"array","title":"Card Facts"},"has_photo":{"type":"boolean","title":"Has Photo"},"has_value":{"type":"boolean","title":"Has Value"}},"type":"object","required":["gem_id","stories","people","suggestions","on_schedule","links","card_facts","has_photo","has_value"],"title":"RecordOut"},"RecordPatch":{"properties":{"on_schedule":{"type":"boolean","title":"On Schedule"}},"type":"object","required":["on_schedule"],"title":"RecordPatch"},"RecordsUpdateRequest":{"properties":{"length_mm":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Length Mm"},"width_mm":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Width Mm"},"depth_mm":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Depth Mm"},"carat":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Carat"},"stone_quantity":{"anyOf":[{"type":"integer","maximum":100000.0,"minimum":1.0},{"type":"null"}],"title":"Stone Quantity"},"carat_scope":{"anyOf":[{"type":"string","enum":["per_stone","total"]},{"type":"null"}],"title":"Carat Scope"},"lab_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lab Name"},"certificate_number":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Certificate Number"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"},"reference_number":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reference Number"},"watch_year":{"anyOf":[{"type":"integer","maximum":2100.0,"minimum":1800.0},{"type":"null"}],"title":"Watch Year"},"box_papers":{"anyOf":[{"type":"string","enum":["full_set","papers","box","none"]},{"type":"null"}],"title":"Box Papers"},"watch_condition":{"anyOf":[{"type":"string","enum":["unworn","excellent","good","worn"]},{"type":"null"}],"title":"Watch Condition"}},"type":"object","title":"RecordsUpdateRequest","description":"Body for PATCH /api/v1/gems/{gem_id}/records.\n\nTrue partial patch: an omitted field is left untouched, an explicit null\nclears that one field. The route reads ``model_fields_set`` to tell those\napart — do not add defaults that would blur the distinction."},"ReferralMeResponse":{"properties":{"referral_code":{"type":"string","title":"Referral Code"},"share_url":{"type":"string","title":"Share Url"},"referred_count":{"type":"integer","title":"Referred Count"},"scans_earned":{"type":"integer","title":"Scans Earned"}},"type":"object","required":["referral_code","share_url","referred_count","scans_earned"],"title":"ReferralMeResponse"},"ReferralRedeemRequest":{"properties":{"code":{"type":"string","maxLength":32,"minLength":1,"title":"Code"}},"type":"object","required":["code"],"title":"ReferralRedeemRequest"},"ReferralRedeemResponse":{"properties":{"granted":{"type":"boolean","title":"Granted"},"bonus_scans":{"type":"integer","title":"Bonus Scans"},"message":{"type":"string","title":"Message"}},"type":"object","required":["granted","bonus_scans","message"],"title":"ReferralRedeemResponse"},"RefreshTokenRequest":{"properties":{"refreshToken":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Refreshtoken"}},"type":"object","title":"RefreshTokenRequest"},"RelationshipIn":{"properties":{"status":{"anyOf":[{"type":"string","enum":["owned","considering","wishlist","researching","previously_owned"]},{"type":"null"}],"title":"Status"},"use":{"anyOf":[{"type":"string","enum":["daily","occasional","special_occasion","display","storage"]},{"type":"null"}],"title":"Use"},"commerce":{"anyOf":[{"type":"string","enum":["browsing","buying","selling","none"]},{"type":"null"}],"title":"Commerce"},"shopping":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Shopping"}},"type":"object","title":"RelationshipIn"},"RelationshipRowOut":{"properties":{"key":{"type":"string","title":"Key"},"value":{"type":"string","title":"Value"},"text":{"type":"string","title":"Text"},"quote":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Quote"},"basis":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Basis"},"ids":{"items":{"type":"integer"},"type":"array","title":"Ids","default":[]}},"type":"object","required":["key","value","text"],"title":"RelationshipRowOut"},"ReleaseNoteCreate":{"properties":{"title":{"type":"string","maxLength":140,"minLength":1,"title":"Title"},"body":{"anyOf":[{"type":"string","maxLength":1000},{"type":"null"}],"title":"Body"},"version":{"anyOf":[{"type":"string","maxLength":32},{"type":"null"}],"title":"Version"},"platform":{"type":"string","title":"Platform","default":"all"},"image_url":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Image Url"},"shipped_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Shipped At"},"is_published":{"type":"boolean","title":"Is Published","default":false},"is_featured":{"type":"boolean","title":"Is Featured","default":false}},"type":"object","required":["title"],"title":"ReleaseNoteCreate"},"ReleaseNoteUpdate":{"properties":{"title":{"anyOf":[{"type":"string","maxLength":140,"minLength":1},{"type":"null"}],"title":"Title"},"body":{"anyOf":[{"type":"string","maxLength":1000},{"type":"null"}],"title":"Body"},"version":{"anyOf":[{"type":"string","maxLength":32},{"type":"null"}],"title":"Version"},"platform":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Platform"},"image_url":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Image Url"},"shipped_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Shipped At"},"is_published":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Published"},"is_featured":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Featured"}},"type":"object","title":"ReleaseNoteUpdate"},"ReminderOut":{"properties":{"id":{"type":"integer","title":"Id"},"gem_id":{"type":"integer","title":"Gem Id"},"kind":{"type":"string","enum":["reminder","attention"],"title":"Kind"},"status":{"type":"string","title":"Status"},"criteria":{"type":"object","title":"Criteria","default":{}},"due_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Due At"},"timezone":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Timezone"},"closed_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Closed Reason"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","gem_id","kind","status","created_at"],"title":"ReminderOut"},"ReportListResponse":{"properties":{"total":{"type":"integer","title":"Total"},"reports":{"items":{"$ref":"#/components/schemas/ReportOut"},"type":"array","title":"Reports"}},"type":"object","required":["total","reports"],"title":"ReportListResponse"},"ReportOut":{"properties":{"id":{"type":"integer","title":"Id"},"target_type":{"type":"string","title":"Target Type"},"target_id":{"type":"integer","title":"Target Id"},"reporter_user_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Reporter User Id"},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason"},"detail":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Detail"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"resolved_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Resolved At"},"resolution":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Resolution"},"content":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Content"},"content_author_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Content Author Id"},"content_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Content Status"},"report_count":{"type":"integer","title":"Report Count","default":1}},"type":"object","required":["id","target_type","target_id","created_at"],"title":"ReportOut"},"ReportRequest":{"properties":{"target_type":{"type":"string","title":"Target Type"},"target_id":{"type":"integer","title":"Target Id"},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason"},"detail":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Detail"}},"type":"object","required":["target_type","target_id"],"title":"ReportRequest"},"ResolveRequest":{"properties":{"resolution":{"type":"string","title":"Resolution"},"note":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Note"}},"type":"object","required":["resolution"],"title":"ResolveRequest"},"ResolveResponse":{"properties":{"ok":{"type":"boolean","title":"Ok","default":true},"resolution":{"type":"string","title":"Resolution"},"removed":{"type":"boolean","title":"Removed","default":false}},"type":"object","required":["resolution"],"title":"ResolveResponse"},"ReviewIn":{"properties":{"decision":{"type":"string","enum":["approve","reject"],"title":"Decision"},"note":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Note"}},"type":"object","required":["decision"],"title":"ReviewIn"},"SaleRecord":{"properties":{"dealer_sale_id":{"type":"string","title":"Dealer Sale Id","description":"Unique dealer-tools InventoryItem ID"},"dealer_id":{"type":"string","title":"Dealer Id","description":"Dealer tenant ID (e.g. 'demo-dealer')"},"sold_price":{"type":"number","exclusiveMinimum":0.0,"title":"Sold Price","description":"Closing price in USD"},"carat_weight":{"type":"number","exclusiveMinimum":0.0,"title":"Carat Weight","description":"Weight in carats"},"sold_at":{"type":"string","format":"date-time","title":"Sold At","description":"ISO timestamp of sale close"},"sale_channel":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sale Channel","description":"IN_STORE / SHOWCASE_INQUIRY / WEBSITE / CONSIGNMENT / INVOICE / MEMO"},"gem_species":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Gem Species"},"gem_variety":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Gem Variety"},"color_description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Color Description"},"color_hue":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Color Hue"},"color_saturation":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Color Saturation"},"color_tone":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Color Tone"},"clarity":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Clarity"},"cut_shape":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cut Shape"},"cutting_style":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cutting Style"},"origin":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Origin"},"treatment":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Treatment"},"treatment_details":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Treatment Details"},"transparency":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Transparency"},"certificate_lab":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Certificate Lab"},"certificate_number":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Certificate Number"},"is_lab_grown":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Lab Grown"}},"type":"object","required":["dealer_sale_id","dealer_id","sold_price","carat_weight","sold_at"],"title":"SaleRecord","description":"A single closed-sale record exported from dealer-tools."},"SalesIngestRequest":{"properties":{"sales":{"items":{"$ref":"#/components/schemas/SaleRecord"},"type":"array","maxItems":1000,"minItems":1,"title":"Sales"}},"type":"object","required":["sales"],"title":"SalesIngestRequest","description":"Body of POST /api/v1/pricing/sales/ingest."},"SalesIngestResponse":{"properties":{"received":{"type":"integer","title":"Received"},"ingested":{"type":"integer","title":"Ingested"},"dedup_skipped":{"type":"integer","title":"Dedup Skipped"},"invalid_skipped":{"type":"integer","title":"Invalid Skipped"},"errors":{"items":{"type":"string"},"type":"array","title":"Errors"},"batch_as_of":{"type":"string","format":"date-time","title":"Batch As Of"}},"type":"object","required":["received","ingested","dedup_skipped","invalid_skipped","batch_as_of"],"title":"SalesIngestResponse","description":"Result summary. `dedup_skipped` are rows we already have on file."},"SavedGemstoneResponse":{"properties":{"id":{"type":"integer","title":"Id"},"user_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"User Id"},"scan_saved_to_collection":{"type":"boolean","title":"Scan Saved To Collection","default":false},"main_heading":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Main Heading"},"sub_heading":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sub Heading"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"estimated_value":{"anyOf":[{"$ref":"#/components/schemas/EstimatedValue"},{"type":"string"},{"type":"null"}],"title":"Estimated Value"},"valuation_basis":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Valuation Basis"},"stone_quantity":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Stone Quantity"},"observed_colors":{"anyOf":[{"items":{"type":"object"},"type":"array"},{"type":"null"}],"title":"Observed Colors"},"gem_species":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Gem Species"},"gem_species_confidence":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Gem Species Confidence"},"top_3_candidates":{"anyOf":[{"items":{},"type":"array"},{"type":"null"}],"title":"Top 3 Candidates"},"jewelry_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Jewelry Type"},"metal_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Metal Type"},"metal_detected":{"type":"boolean","title":"Metal Detected","default":false},"gemstone_detected":{"type":"boolean","title":"Gemstone Detected","default":true},"loose_gem":{"type":"boolean","title":"Loose Gem","default":false},"value_trend":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Value Trend","default":"0"},"primary_stone":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Primary Stone"},"scan_quality":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Scan Quality"},"alternatives":{"anyOf":[{"items":{"$ref":"#/components/schemas/AlternativeIdentification"},"type":"array"},{"type":"null"}],"title":"Alternatives"},"origin_estimate":{"anyOf":[{"$ref":"#/components/schemas/OriginEstimate"},{"type":"null"}]},"clarity_estimate":{"anyOf":[{"$ref":"#/components/schemas/ClarityEstimate"},{"type":"null"}]},"treatment_estimate":{"anyOf":[{"$ref":"#/components/schemas/TreatmentEstimate"},{"type":"null"}]},"dimensions_estimate":{"anyOf":[{"$ref":"#/components/schemas/DimensionsEstimate"},{"type":"null"}]},"transparency_estimate":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Transparency Estimate"},"carat_estimate":{"anyOf":[{"$ref":"#/components/schemas/CaratEstimate"},{"type":"null"}]},"carat_scope":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Carat Scope"},"total_carat_weight":{"anyOf":[{},{"type":"null"}],"title":"Total Carat Weight"},"watch":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Watch"},"cut_shape":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cut Shape"},"color_grade":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Color Grade"},"color_grade_confidence":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Color Grade Confidence"},"clarity_grade":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Clarity Grade"},"clarity_grade_confidence":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Clarity Grade Confidence"},"cut_grade":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cut Grade"},"cut_grade_confidence":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Cut Grade Confidence"},"origin_grade":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Origin Grade"},"origin_grade_confidence":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Origin Grade Confidence"},"treatment_grade":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Treatment Grade"},"treatment_grade_confidence":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Treatment Grade Confidence"},"color_profile":{"anyOf":[{"$ref":"#/components/schemas/ColorProfile"},{"type":"null"}]},"jewelry_specifications":{"anyOf":[{"$ref":"#/components/schemas/JewelrySpecifications"},{"type":"null"}]},"stone_specifications":{"anyOf":[{"items":{"$ref":"#/components/schemas/StoneSpec"},"type":"array"},{"type":"null"}],"title":"Stone Specifications"},"about":{"anyOf":[{"$ref":"#/components/schemas/app__schemas__gemstone__About"},{"type":"null"}]},"market_insights":{"anyOf":[{"$ref":"#/components/schemas/app__schemas__gemstone__MarketInsights"},{"type":"null"}]},"value_breakdown":{"anyOf":[{},{"type":"null"}],"title":"Value Breakdown"},"authenticity":{"anyOf":[{},{"type":"null"}],"title":"Authenticity"},"comparables":{"anyOf":[{"items":{},"type":"array"},{"type":"null"}],"title":"Comparables"},"scan_version":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Scan Version"},"analysis":{"anyOf":[{},{"type":"null"}],"title":"Analysis"},"composition":{"anyOf":[{},{"type":"null"}],"title":"Composition"},"value":{"anyOf":[{},{"type":"null"}],"title":"Value"},"confidence":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Confidence"},"specimen_form":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Specimen Form"},"id_agreement":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Id Agreement"},"photo_guidance":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Photo Guidance"},"capture_issue":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Capture Issue"},"stage1_species":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Stage1 Species"},"final_species":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Final Species"},"deep_scan_status":{"type":"string","title":"Deep Scan Status","default":"pending"},"deep_scan_started_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Deep Scan Started At"},"deep_scan_completed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Deep Scan Completed At"},"brand":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Brand"},"product_line":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Product Line"},"brand_source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Brand Source"},"brand_confidence":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Brand Confidence"},"brand_evidence":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Brand Evidence"},"images":{"items":{"$ref":"#/components/schemas/GemstoneImageResponse"},"type":"array","title":"Images","default":[]},"scan_accuracy_feedback":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Scan Accuracy Feedback"},"market":{"anyOf":[{"$ref":"#/components/schemas/GemMarketBlock"},{"type":"null"}]},"investment":{"anyOf":[{"$ref":"#/components/schemas/GemInvestmentBlock"},{"type":"null"}]},"records":{"anyOf":[{"$ref":"#/components/schemas/GemRecordsBlock"},{"type":"null"}]},"identification":{"anyOf":[{"$ref":"#/components/schemas/GemIdentificationBlock"},{"type":"null"}]},"species_source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Species Source"},"species_shortlist":{"anyOf":[{"items":{"$ref":"#/components/schemas/ShortlistOption"},"type":"array"},{"type":"null"}],"title":"Species Shortlist"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"},"bonus_granted":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Bonus Granted"},"scans_remaining":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Scans Remaining"}},"type":"object","required":["id","created_at","updated_at"],"title":"SavedGemstoneResponse","description":"GemstoneResponse + scan-bonus-ladder fields for POST /gems/save/collection.\n\nLNK-LADDER: the first save-to-collection grants +1 bonus scan. The response\nstays a JSON array (old clients ignore the extra per-item keys); each item\ncarries the same bonus payload so clients can read it from any element."},"ScanFeedbackRequest":{"properties":{"gemstone_id":{"type":"integer","title":"Gemstone Id"},"is_accurate":{"type":"boolean","title":"Is Accurate"}},"type":"object","required":["gemstone_id","is_accurate"],"title":"ScanFeedbackRequest"},"ScanFeedbackResponse":{"properties":{"success":{"type":"boolean","title":"Success"},"message":{"type":"string","title":"Message"},"gemstone_id":{"type":"integer","title":"Gemstone Id"}},"type":"object","required":["success","message","gemstone_id"],"title":"ScanFeedbackResponse"},"ScanLimitCheckResponse":{"properties":{"device_id":{"type":"string","title":"Device Id"},"can_scan":{"type":"boolean","title":"Can Scan"},"scans_remaining":{"anyOf":[{"type":"integer"},{"type":"string"}],"title":"Scans Remaining"},"scans_used":{"type":"integer","title":"Scans Used"},"scan_limit":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Scan Limit"},"plan_type":{"type":"string","title":"Plan Type"},"user_status":{"type":"string","title":"User Status"},"message":{"type":"string","title":"Message"},"linked_to_user":{"type":"boolean","title":"Linked To User","default":false},"action_required":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Action Required"},"tier":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tier"},"resets_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Resets At"},"upgrade_tier":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Upgrade Tier"}},"type":"object","required":["device_id","can_scan","scans_remaining","scans_used","plan_type","user_status","message"],"title":"ScanLimitCheckResponse","description":"Response for scan limit check API","example":{"can_scan":true,"linked_to_user":false,"message":"3 free scans remaining","plan_type":"free","scan_limit":5,"scans_remaining":3,"scans_used":2,"user_status":"anonymous"}},"ScanNotice":{"properties":{"code":{"type":"string","title":"Code"},"severity":{"type":"string","enum":["info","warn"],"title":"Severity","default":"info"},"message":{"type":"string","maxLength":240,"minLength":1,"title":"Message"}},"type":"object","required":["code","message"],"title":"ScanNotice","description":"One thing worth telling the user about this scan. [LNK-NOTICES]\n\n`authenticity` had become the dumping ground for three unrelated concerns:\na genuine authenticity doubt (is this stone what it appears to be), the\ncross-scan divergence banner (LNK-SCANFIX), and the within-scan\nself-consistency banner (LNK-SELFCON). It holds exactly ONE message, so each\nnew concern had to fight the others for the slot — every writer needed a\n\"do not clobber a real authenticity warning\" rule, and the next one added\nwould have been the one that forgot.\n\n`notices` is a list, so concerns coexist and each carries its own `code`.\n`authenticity` keeps its exact existing behaviour for the shipped app.\n\n`code` is a plain str, not a Literal, so a new reason never fails\nvalidation on an older client."},"ScanTierQuota":{"properties":{"tier":{"type":"string","title":"Tier"},"scans_used":{"type":"integer","title":"Scans Used"},"scans_limit":{"type":"integer","title":"Scans Limit"},"scans_remaining":{"type":"integer","title":"Scans Remaining"},"resets_at":{"type":"string","title":"Resets At"},"upgrade_tier":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Upgrade Tier"}},"type":"object","required":["tier","scans_used","scans_limit","scans_remaining","resets_at"],"title":"ScanTierQuota","description":"Monthly allowance of a capped paid tier (LNK-SCANTIERS). Null on\nfree plans and on unlimited (pre-tier) Premium."},"ScanV2ErrorResponse":{"properties":{"is_gemstone":{"const":false,"title":"Is Gemstone","default":false},"scan_version":{"const":2,"title":"Scan Version","default":2},"error":{"type":"string","title":"Error"},"message":{"type":"string","title":"Message"}},"type":"object","required":["error","message"],"title":"ScanV2ErrorResponse","description":"Returned when the AI rejects the image as non-gemstone or analysis fails."},"ScanV2GemstoneImage":{"properties":{"id":{"type":"integer","title":"Id"},"image_url":{"type":"string","title":"Image Url"},"thumb_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Thumb Url"}},"type":"object","required":["id","image_url"],"title":"ScanV2GemstoneImage","description":"Image attached to a scan_v2 result."},"ScanV2Result":{"properties":{"pricing":{"anyOf":[{"$ref":"#/components/schemas/PricingResult"},{"type":"null"}]},"is_gemstone":{"type":"boolean","title":"Is Gemstone","default":true},"scan_version":{"const":2,"title":"Scan Version","default":2},"main_heading":{"type":"string","title":"Main Heading"},"sub_heading":{"type":"string","title":"Sub Heading"},"loose_gem":{"type":"boolean","title":"Loose Gem"},"specimen_form":{"anyOf":[{"type":"string","enum":["faceted_stone","cabochon","bead_carving","pearl","rough_crystal","mineral_specimen","jewelry_mounted"]},{"type":"null"}],"title":"Specimen Form"},"primary_stone":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Primary Stone"},"primary_color":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Primary Color"},"gem_species":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Gem Species"},"gem_species_confidence":{"type":"integer","maximum":100.0,"minimum":0.0,"title":"Gem Species Confidence","default":0},"top_3_candidates":{"items":{"$ref":"#/components/schemas/TopCandidate"},"type":"array","title":"Top 3 Candidates"},"jewelry_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Jewelry Type"},"metal_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Metal Type"},"piece_class":{"anyOf":[{"type":"string","enum":["fine","fashion"]},{"type":"null"}],"title":"Piece Class"},"metal_weight_grams":{"anyOf":[{"type":"number","minimum":0.0},{"type":"null"}],"title":"Metal Weight Grams"},"authenticity":{"anyOf":[{"$ref":"#/components/schemas/Authenticity"},{"type":"null"}]},"printed_claims_seen":{"type":"boolean","title":"Printed Claims Seen","default":false},"notices":{"items":{"$ref":"#/components/schemas/ScanNotice"},"type":"array","title":"Notices"},"estimated_value":{"anyOf":[{"$ref":"#/components/schemas/EstimatedValueV2"},{"type":"null"}]},"value":{"anyOf":[{"$ref":"#/components/schemas/ValueBreakdownV2"},{"type":"null"}]},"analysis":{"$ref":"#/components/schemas/Analysis"},"comparables":{"items":{"$ref":"#/components/schemas/ComparableListing"},"type":"array","maxItems":4,"title":"Comparables"},"comparables_disclaimer":{"type":"string","title":"Comparables Disclaimer","default":""},"market_insights":{"anyOf":[{"$ref":"#/components/schemas/app__schemas__scan_v2__MarketInsights"},{"type":"null"}]},"about":{"anyOf":[{"$ref":"#/components/schemas/app__schemas__scan_v2__About"},{"type":"null"}]},"composition":{"anyOf":[{"$ref":"#/components/schemas/Composition"},{"type":"null"}]},"origin_estimate":{"anyOf":[{"$ref":"#/components/schemas/OriginEstimateV2"},{"type":"null"}]},"clarity_estimate":{"anyOf":[{"$ref":"#/components/schemas/ClarityEstimateV2"},{"type":"null"}]},"treatment_estimate":{"anyOf":[{"$ref":"#/components/schemas/TreatmentEstimateV2"},{"type":"null"}]},"dimensions_estimate":{"anyOf":[{"$ref":"#/components/schemas/DimensionsEstimateV2"},{"type":"null"}]},"carat_estimate":{"anyOf":[{"$ref":"#/components/schemas/CaratEstimateV2"},{"type":"null"}]},"carat_scope":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Carat Scope"},"stone_quantity":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Stone Quantity"},"observed_colors":{"anyOf":[{"items":{"type":"object"},"type":"array"},{"type":"null"}],"title":"Observed Colors"},"valuation_basis":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Valuation Basis"},"total_carat_weight":{"anyOf":[{"$ref":"#/components/schemas/TotalCaratWeightV2"},{"type":"null"}]},"transparency_estimate":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Transparency Estimate"},"color_grade":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Color Grade"},"color_grade_confidence":{"anyOf":[{"type":"integer","maximum":100.0,"minimum":0.0},{"type":"null"}],"title":"Color Grade Confidence"},"clarity_grade":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Clarity Grade"},"clarity_grade_confidence":{"anyOf":[{"type":"integer","maximum":100.0,"minimum":0.0},{"type":"null"}],"title":"Clarity Grade Confidence"},"cut_grade":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cut Grade"},"cut_grade_confidence":{"anyOf":[{"type":"integer","maximum":100.0,"minimum":0.0},{"type":"null"}],"title":"Cut Grade Confidence"},"origin_grade":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Origin Grade"},"origin_grade_confidence":{"anyOf":[{"type":"integer","maximum":100.0,"minimum":0.0},{"type":"null"}],"title":"Origin Grade Confidence"},"treatment_grade":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Treatment Grade"},"treatment_grade_confidence":{"anyOf":[{"type":"integer","maximum":100.0,"minimum":0.0},{"type":"null"}],"title":"Treatment Grade Confidence"},"confidence":{"type":"integer","maximum":100.0,"minimum":0.0,"title":"Confidence","default":0},"scan_quality":{"type":"string","enum":["High","Good","Fair"],"title":"Scan Quality","default":"Good"},"alternatives":{"items":{"$ref":"#/components/schemas/AlternativeV2"},"type":"array","title":"Alternatives"},"species_shortlist":{"anyOf":[{"items":{"$ref":"#/components/schemas/ShortlistOption"},"type":"array"},{"type":"null"}],"title":"Species Shortlist"},"id_agreement":{"type":"string","enum":["confirmed","family_match","divergent","unverified"],"title":"Id Agreement","default":"unverified"},"id_agreement_basis":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Id Agreement Basis"},"identity_revision":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Identity Revision"},"pricing_evidence":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Pricing Evidence"},"pipeline_version":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pipeline Version"},"unresolved":{"items":{"type":"string"},"type":"array","title":"Unresolved"},"stage1_species":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Stage1 Species"},"final_species":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Final Species"},"photo_guidance":{"type":"string","enum":["good","add_angle","retake"],"title":"Photo Guidance","default":"good"},"capture_issue":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Capture Issue"},"value_breakdown":{"anyOf":[{},{"type":"null"}],"title":"Value Breakdown"},"stone_specifications":{"anyOf":[{},{"type":"null"}],"title":"Stone Specifications"},"reconciliation":{"anyOf":[{"$ref":"#/components/schemas/ReconciliationTrace"},{"type":"null"}]},"consensus":{"anyOf":[{"$ref":"#/components/schemas/ConsensusTrace"},{"type":"null"}]},"brand_identification":{"anyOf":[{"$ref":"#/components/schemas/BrandIdentificationBlock"},{"type":"null"}]},"watch":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Watch"}},"type":"object","required":["main_heading","sub_heading","loose_gem","analysis"],"title":"ScanV2Result"},"ScanV2SuccessResponse":{"properties":{"success":{"const":true,"title":"Success","default":true},"gemstone_id":{"type":"integer","title":"Gemstone Id"},"images":{"items":{"$ref":"#/components/schemas/ScanV2GemstoneImage"},"type":"array","title":"Images"},"scan":{"$ref":"#/components/schemas/ScanV2Result"},"scan_refunded":{"type":"boolean","title":"Scan Refunded","default":false},"possible_same_as":{"anyOf":[{"$ref":"#/components/schemas/PossibleSamePiece"},{"type":"null"}]}},"type":"object","required":["gemstone_id","scan"],"title":"ScanV2SuccessResponse","description":"Wire response for a successful POST /api/v1/gems/scan in the v2 pipeline.\n\nCombines the persisted Gemstone row id + image list with the full\nScanV2Result the mobile result screen renders. Mobile reads `gemstone_id`\nto wire collection-save and chat-refinement flows, and `scan` for the UI."},"ScheduleEditionRequest":{"properties":{"scheduled_for":{"type":"string","format":"date-time","title":"Scheduled For"},"audience":{"type":"string","title":"Audience","default":"free"}},"type":"object","required":["scheduled_for"],"title":"ScheduleEditionRequest"},"ScheduleLinkRequest":{"properties":{"gemstone_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Gemstone Id","description":"Omit for the whole collection"}},"type":"object","title":"ScheduleLinkRequest"},"ScheduleLinkResponse":{"properties":{"url":{"type":"string","title":"Url"},"expires_in_days":{"type":"integer","title":"Expires In Days"},"item_count":{"type":"integer","title":"Item Count"},"total_value":{"type":"number","title":"Total Value"}},"type":"object","required":["url","expires_in_days","item_count","total_value"],"title":"ScheduleLinkResponse"},"ScheduleRequest":{"properties":{"content_output_id":{"type":"integer","title":"Content Output Id"},"platform":{"type":"string","title":"Platform"},"account_handle":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Account Handle"},"scheduled_for":{"type":"string","format":"date-time","title":"Scheduled For"}},"type":"object","required":["content_output_id","platform","scheduled_for"],"title":"ScheduleRequest"},"SendEmailOTPRequest":{"properties":{"email":{"type":"string","title":"Email","description":"Email address to send OTP to"}},"type":"object","required":["email"],"title":"SendEmailOTPRequest"},"SendOTPRequest":{"properties":{"mobile_number":{"type":"string","title":"Mobile Number","description":"Full phone number with country code (e.g., '+911234567890')"},"phone_country_code":{"type":"string","title":"Phone Country Code","description":"Country code (e.g., '+91')"}},"type":"object","required":["mobile_number","phone_country_code"],"title":"SendOTPRequest"},"SetCoverRequest":{"properties":{"cover_image_id":{"type":"integer","title":"Cover Image Id"}},"type":"object","required":["cover_image_id"],"title":"SetCoverRequest"},"ShortlistOption":{"properties":{"species":{"type":"string","title":"Species"},"label":{"type":"string","title":"Label"}},"type":"object","required":["species","label"],"title":"ShortlistOption","description":"One name in a lookalike shortlist [LNK-SHORTLIST]. `species` is the\ntaxonomy name to send back to PATCH /gems/{id}/identification."},"SimpleOk":{"properties":{"ok":{"type":"boolean","title":"Ok","default":true},"message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Message"}},"type":"object","title":"SimpleOk"},"SpeciesAllocation":{"properties":{"species":{"type":"string","title":"Species"},"value":{"type":"number","title":"Value"},"pct":{"type":"number","title":"Pct"},"count":{"type":"integer","title":"Count"}},"type":"object","required":["species","value","pct","count"],"title":"SpeciesAllocation"},"SpeciesContentResponse":{"properties":{"history_lore":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"History Lore"},"cultural_significance":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cultural Significance"},"geology_paragraph":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Geology Paragraph"},"famous_stones":{"anyOf":[{"items":{"type":"object"},"type":"array"},{"type":"null"}],"title":"Famous Stones"},"buyers_guide":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Buyers Guide"},"synthetic_species":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Synthetic Species"},"simulants":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Simulants"},"common_treatments":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Common Treatments"},"origin_subregions":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Origin Subregions"},"species":{"type":"string","title":"Species","description":"Species name, e.g. 'Emerald'"},"content_version":{"type":"integer","title":"Content Version"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["species","content_version","updated_at"],"title":"SpeciesContentResponse"},"SpeciesContentUpsert":{"properties":{"history_lore":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"History Lore"},"cultural_significance":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cultural Significance"},"geology_paragraph":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Geology Paragraph"},"famous_stones":{"anyOf":[{"items":{"type":"object"},"type":"array"},{"type":"null"}],"title":"Famous Stones"},"buyers_guide":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Buyers Guide"},"synthetic_species":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Synthetic Species"},"simulants":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Simulants"},"common_treatments":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Common Treatments"},"origin_subregions":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Origin Subregions"}},"type":"object","title":"SpeciesContentUpsert","description":"Body for PUT — all fields optional. Server bumps content_version + sets last_edited_by."},"StoneSpec":{"properties":{"stone":{"type":"string","title":"Stone"},"quantity":{"type":"integer","title":"Quantity"},"carat":{"type":"string","title":"Carat"},"cut":{"type":"string","title":"Cut"},"color":{"type":"string","title":"Color"},"clarity":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Clarity"}},"type":"object","required":["stone","quantity","carat","cut","color"],"title":"StoneSpec","description":"Single stone specification"},"StoryOut":{"properties":{"id":{"type":"integer","title":"Id"},"text":{"type":"string","title":"Text"},"basis":{"type":"string","enum":["recollection","documented"],"title":"Basis"},"label":{"type":"string","title":"Label"},"kept_from_chat":{"type":"boolean","title":"Kept From Chat","default":false},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updated At"}},"type":"object","required":["id","text","basis","label"],"title":"StoryOut"},"StudioRender":{"properties":{"image_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Image Url"},"thumb_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Thumb Url"}},"type":"object","title":"StudioRender"},"StudioRendersResponse":{"properties":{"items":{"additionalProperties":{"$ref":"#/components/schemas/StudioRender"},"type":"object","title":"Items","default":{}}},"type":"object","title":"StudioRendersResponse","description":"gem_id -> the piece's studio render, for the Collection grid [LNK-ILLUS]."},"SubmitEntryRequest":{"properties":{"gemstone_id":{"type":"integer","title":"Gemstone Id"},"cover_image_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Cover Image Id"},"is_anonymous":{"type":"boolean","title":"Is Anonymous","default":false}},"type":"object","required":["gemstone_id"],"title":"SubmitEntryRequest"},"SubmitRatingRequest":{"properties":{"rating_value":{"type":"integer","maximum":5.0,"minimum":1.0,"title":"Rating Value","description":"Star rating (1-5)"},"comment":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Comment","description":"Optional comment"}},"type":"object","required":["rating_value"],"title":"SubmitRatingRequest","description":"Request to submit app rating","example":{"comment":"Great app for identifying gemstones!","rating_value":5}},"SubmitRatingResponse":{"properties":{"success":{"type":"boolean","title":"Success"},"message":{"type":"string","title":"Message"},"rating_id":{"type":"integer","title":"Rating Id"},"rating_value":{"type":"integer","title":"Rating Value"},"bonus_scans_granted":{"type":"integer","title":"Bonus Scans Granted"},"new_scans_available":{"type":"integer","title":"New Scans Available"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["success","message","rating_id","rating_value","bonus_scans_granted","new_scans_available","created_at"],"title":"SubmitRatingResponse","description":"Response after submitting rating"},"SubscriberListResponse":{"properties":{"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"page_size":{"type":"integer","title":"Page Size"},"items":{"items":{"$ref":"#/components/schemas/SubscriberResponse"},"type":"array","title":"Items"}},"type":"object","required":["total","page","page_size","items"],"title":"SubscriberListResponse"},"SubscriberResponse":{"properties":{"id":{"type":"integer","title":"Id"},"email":{"type":"string","title":"Email"},"first_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"First Name"},"last_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Name"},"company_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Company Name"},"subscribed_at":{"type":"string","format":"date-time","title":"Subscribed At"},"source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source"},"segments":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Segments"},"lifecycle_stage":{"type":"string","title":"Lifecycle Stage"},"prospect_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Prospect Id"},"beehiiv_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Beehiiv Id"},"unsubscribed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Unsubscribed At"},"referral_count":{"type":"integer","title":"Referral Count","default":0}},"type":"object","required":["id","email","subscribed_at","lifecycle_stage"],"title":"SubscriberResponse"},"SubscriberSignupRequest":{"properties":{"email":{"type":"string","format":"email","title":"Email"},"first_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"First Name"},"last_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Name"},"company_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Company Name"},"source":{"type":"string","title":"Source","default":"unknown"},"segments":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Segments"},"utm_source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Utm Source"},"utm_medium":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Utm Medium"},"utm_campaign":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Utm Campaign"},"referring_site":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Referring Site"}},"type":"object","required":["email"],"title":"SubscriberSignupRequest"},"SubscriberSignupResponse":{"properties":{"id":{"type":"integer","title":"Id"},"email":{"type":"string","title":"Email"},"status":{"type":"string","title":"Status"},"beehiiv_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Beehiiv Id"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","email","status","created_at"],"title":"SubscriberSignupResponse"},"SubscriptionStatusDetailedResponse":{"properties":{"plan_name":{"type":"string","title":"Plan Name"},"plan_display_name":{"type":"string","title":"Plan Display Name"},"status":{"type":"string","title":"Status"},"scans_used_this_month":{"type":"integer","title":"Scans Used This Month"},"scans_remaining":{"anyOf":[{"type":"string"},{"type":"integer"}],"title":"Scans Remaining"},"scans_limit":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Scans Limit"},"collection_count":{"type":"integer","title":"Collection Count"},"collection_limit":{"anyOf":[{"type":"string"},{"type":"integer"}],"title":"Collection Limit"},"billing_period":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Billing Period"},"next_billing_date":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Next Billing Date"},"cancel_at_period_end":{"type":"boolean","title":"Cancel At Period End","default":false},"start_date":{"type":"string","format":"date-time","title":"Start Date"},"current_period_end":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Current Period End"},"scan_tier":{"anyOf":[{"$ref":"#/components/schemas/ScanTierQuota"},{"type":"null"}]}},"type":"object","required":["plan_name","plan_display_name","status","scans_used_this_month","scans_remaining","scans_limit","collection_count","collection_limit","start_date"],"title":"SubscriptionStatusDetailedResponse","description":"Detailed subscription status including limits and usage"},"SuggestionOut":{"properties":{"ids":{"items":{"type":"integer"},"type":"array","title":"Ids"},"kind":{"type":"string","enum":["story","person"],"title":"Kind"},"text":{"type":"string","title":"Text"},"quote":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Quote"},"role":{"anyOf":[{"type":"string","enum":["from","for"]},{"type":"null"}],"title":"Role"},"relation":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Relation"}},"type":"object","required":["ids","kind","text"],"title":"SuggestionOut","description":"Something the owner said in chat that could go in the record. Never\nadded on its own: the owner keeps it or dismisses it."},"SummaryItemOut":{"properties":{"kind":{"type":"string","enum":["finding","reminder_upcoming","question"],"title":"Kind"},"finding_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Finding Id"},"request_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Request Id"},"gem_id":{"type":"integer","title":"Gem Id"},"title":{"type":"string","title":"Title"},"body":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Body"},"image_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Image Url"},"at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"At"},"finding_kind":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Finding Kind"},"gem_ids":{"items":{"type":"integer"},"type":"array","title":"Gem Ids","default":[]},"lead":{"type":"boolean","title":"Lead","default":false},"card":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Card"},"claims":{"anyOf":[{"items":{"type":"object"},"type":"array"},{"type":"null"}],"title":"Claims"},"why":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Why"},"listing":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Listing"},"basis_note":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Basis Note"}},"type":"object","required":["kind","gem_id","title"],"title":"SummaryItemOut"},"SummaryOut":{"properties":{"items":{"items":{"$ref":"#/components/schemas/SummaryItemOut"},"type":"array","title":"Items"},"piece_flags":{"additionalProperties":{"type":"string","enum":["new_finding","needs_input"]},"type":"object","title":"Piece Flags"}},"type":"object","required":["items","piece_flags"],"title":"SummaryOut"},"SupplyBlock":{"properties":{"variety":{"type":"string","title":"Variety"},"top_origins":{"items":{},"type":"array","title":"Top Origins","default":[]},"supply_concentration_score":{"type":"number","title":"Supply Concentration Score"},"annual_production_tonnes":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Annual Production Tonnes"},"supply_risk_notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Supply Risk Notes"},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updated At"}},"type":"object","required":["variety","supply_concentration_score"],"title":"SupplyBlock"},"SuppressionEntry":{"properties":{"email":{"type":"string","title":"Email"},"domain":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Domain"},"reason":{"type":"string","title":"Reason"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"}},"type":"object","required":["email","reason"],"title":"SuppressionEntry"},"SuppressionResponse":{"properties":{"id":{"type":"integer","title":"Id"},"email":{"type":"string","title":"Email"},"domain":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Domain"},"reason":{"type":"string","title":"Reason"},"suppressed_at":{"type":"string","format":"date-time","title":"Suppressed At"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"}},"type":"object","required":["id","email","reason","suppressed_at"],"title":"SuppressionResponse"},"Token":{"properties":{"token":{"type":"string","title":"Token"},"refreshToken":{"type":"string","title":"Refreshtoken"},"user":{"$ref":"#/components/schemas/UserResponse"},"gemstones_saved":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Gemstones Saved"},"is_new_user":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is New User"},"promo_granted":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Promo Granted"}},"type":"object","required":["token","refreshToken","user"],"title":"Token"},"TopCandidate":{"properties":{"species":{"type":"string","title":"Species"},"confidence":{"type":"integer","maximum":100.0,"minimum":0.0,"title":"Confidence"}},"type":"object","required":["species","confidence"],"title":"TopCandidate"},"TopMover":{"properties":{"variety":{"type":"string","title":"Variety"},"index_value":{"type":"number","title":"Index Value"},"change_pct":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Change Pct"},"direction":{"type":"string","title":"Direction","default":"flat"},"explanation_headline":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Explanation Headline"},"sparkline_7d":{"items":{"type":"number"},"type":"array","title":"Sparkline 7D","default":[]}},"type":"object","required":["variety","index_value"],"title":"TopMover"},"TopMoversResponse":{"properties":{"period":{"type":"string","title":"Period"},"gainers":{"items":{"$ref":"#/components/schemas/TopMover"},"type":"array","title":"Gainers","default":[]},"losers":{"items":{"$ref":"#/components/schemas/TopMover"},"type":"array","title":"Losers","default":[]}},"type":"object","required":["period"],"title":"TopMoversResponse"},"TotalCaratWeightV2":{"properties":{"best":{"anyOf":[{"type":"number","minimum":0.0},{"type":"null"}],"title":"Best"},"range_min":{"anyOf":[{"type":"number","minimum":0.0},{"type":"null"}],"title":"Range Min"},"range_max":{"anyOf":[{"type":"number","minimum":0.0},{"type":"null"}],"title":"Range Max"},"confidence":{"anyOf":[{"type":"integer","maximum":100.0,"minimum":0.0},{"type":"null"}],"title":"Confidence"}},"type":"object","title":"TotalCaratWeightV2","description":"Combined weight of every stone in a multi-stone piece [LNK-TCW].\n\nSeparate from ``carat_estimate``, which measures ONE stone via the\ndimensions-first method. Collapsing the two into a single unlabelled field\nis what let prod gems 4277 and 4278 — the same bracelet three minutes\napart — report 6.00 ct and 0.12 ct from prose that agreed with itself.\n\nRANGE-ONLY BY DESIGN. Measured on 41 multi-stone prod frames, three\nidentical-byte runs each: median spread 1.30x, p90 1.58x. A point value\nhere would be false precision, so ``best`` must always be read alongside\nrange_min/range_max and never rendered alone."},"TouchpointResponse":{"properties":{"id":{"type":"integer","title":"Id"},"customer_onboarding_id":{"type":"integer","title":"Customer Onboarding Id"},"dealer_customer_id":{"type":"string","title":"Dealer Customer Id"},"touchpoint_type":{"type":"string","title":"Touchpoint Type"},"scheduled_for":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Scheduled For"},"sent_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Sent At"},"channel":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Channel"},"content":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Content"},"response":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Response"},"status":{"type":"string","title":"Status"}},"type":"object","required":["id","customer_onboarding_id","dealer_customer_id","touchpoint_type","status"],"title":"TouchpointResponse"},"TreatmentEstimate":{"properties":{"status":{"type":"string","title":"Status","default":"Unknown"},"confidence":{"type":"integer","title":"Confidence","default":0}},"type":"object","title":"TreatmentEstimate","description":"AI-estimated treatment status with species-aware defaults"},"TreatmentEstimateV2":{"properties":{"status":{"type":"string","title":"Status"},"confidence":{"type":"integer","maximum":100.0,"minimum":0.0,"title":"Confidence","default":0}},"type":"object","required":["status"],"title":"TreatmentEstimateV2"},"UnderstandingOut":{"properties":{"gem_id":{"type":"integer","title":"Gem Id"},"facts":{"items":{"$ref":"#/components/schemas/FactOut"},"type":"array","title":"Facts"},"uncertain":{"items":{"$ref":"#/components/schemas/OpenQuestionOut"},"type":"array","title":"Uncertain"},"relationship":{"items":{"$ref":"#/components/schemas/RelationshipRowOut"},"type":"array","title":"Relationship"},"learned":{"items":{"$ref":"#/components/schemas/LearnedOut"},"type":"array","title":"Learned"}},"type":"object","required":["gem_id","facts","uncertain","relationship","learned"],"title":"UnderstandingOut"},"UnreadCountResponse":{"properties":{"unread_count":{"type":"integer","title":"Unread Count"}},"type":"object","required":["unread_count"],"title":"UnreadCountResponse"},"UpdateReminderIn":{"properties":{"action":{"type":"string","enum":["done","snooze","reschedule","cancel"],"title":"Action"},"due_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Due At"}},"type":"object","required":["action"],"title":"UpdateReminderIn"},"UpdateSubscriptionResponse":{"properties":{"success":{"type":"boolean","title":"Success"},"message":{"type":"string","title":"Message"},"user_id":{"type":"integer","title":"User Id"},"plan_name":{"type":"string","title":"Plan Name"},"subscription_status":{"type":"string","title":"Subscription Status"}},"type":"object","required":["success","message","user_id","plan_name","subscription_status"],"title":"UpdateSubscriptionResponse"},"UserDeletionResponse":{"properties":{"success":{"type":"boolean","title":"Success"},"message":{"type":"string","title":"Message"},"user_id":{"type":"integer","title":"User Id"},"stats_before_deletion":{"type":"object","title":"Stats Before Deletion"},"deleted_counts":{"type":"object","title":"Deleted Counts"}},"type":"object","required":["success","message","user_id","stats_before_deletion","deleted_counts"],"title":"UserDeletionResponse","description":"Response for user data deletion"},"UserPlanDetailsResponse":{"properties":{"plan_id":{"type":"integer","title":"Plan Id"},"plan_name":{"type":"string","title":"Plan Name","description":"Internal name: 'free' or 'premium'"},"plan_display_name":{"type":"string","title":"Plan Display Name","description":"Display name: 'Free' or 'Premium'"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description","description":"Plan description"},"is_active":{"type":"boolean","title":"Is Active","description":"Is subscription currently active?"},"status":{"type":"string","title":"Status","description":"active, cancelled, expired, past_due"},"scans_used_this_month":{"type":"integer","title":"Scans Used This Month"},"scans_remaining":{"anyOf":[{"type":"string"},{"type":"integer"}],"title":"Scans Remaining"},"scans_limit":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Scans Limit"},"collection_count":{"type":"integer","title":"Collection Count"},"collection_slots_remaining":{"anyOf":[{"type":"string"},{"type":"integer"}],"title":"Collection Slots Remaining"},"collection_limit":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Collection Limit"},"features":{"anyOf":[{"additionalProperties":{"items":{"type":"object"},"type":"array"},"type":"object"},{"type":"null"}],"title":"Features","description":"Categorized features: {category: [{feature, value}]}"},"billing_period":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Billing Period"},"price":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Price"},"next_billing_date":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Next Billing Date"},"cancel_at_period_end":{"type":"boolean","title":"Cancel At Period End","default":false},"subscription_start_date":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Subscription Start Date"},"current_period_end":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Current Period End"},"scan_tier":{"anyOf":[{"$ref":"#/components/schemas/ScanTierQuota"},{"type":"null"}]}},"type":"object","required":["plan_id","plan_name","plan_display_name","is_active","status","scans_used_this_month","scans_remaining","scans_limit","collection_count","collection_slots_remaining","collection_limit"],"title":"UserPlanDetailsResponse","description":"Complete plan details including all features and metadata.\n\nUse this API when displaying:\n- Plan comparison pages\n- Settings/account page\n- Upgrade prompts with feature lists\n\nPerfect for: Full plan info display, settings page, upgrade modals","example":{"collection_count":7,"collection_limit":10,"collection_slots_remaining":3,"description":"Perfect for getting started","features":{"Scanning":[{"feature":"Monthly Scans","value":"5 scans"}]},"is_active":true,"plan_display_name":"Free","plan_id":1,"plan_name":"free","scans_limit":5,"scans_remaining":3,"scans_used_this_month":2,"status":"active"}},"UserProfileStats":{"properties":{"total_gems":{"type":"integer","title":"Total Gems"},"portfolio":{"type":"number","title":"Portfolio"},"total_scans":{"type":"integer","title":"Total Scans"},"avg_confidence":{"type":"number","title":"Avg Confidence"},"user":{"$ref":"#/components/schemas/UserResponse"}},"type":"object","required":["total_gems","portfolio","total_scans","avg_confidence","user"],"title":"UserProfileStats"},"UserResponse":{"properties":{"id":{"type":"integer","title":"Id"},"mobile_number":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mobile Number"},"phone_country_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Phone Country Code"},"first_name":{"type":"string","title":"First Name"},"last_name":{"type":"string","title":"Last Name"},"avatar":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Avatar"},"is_verified":{"type":"boolean","title":"Is Verified"},"member_since":{"type":"string","format":"date-time","title":"Member Since"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email"},"registration_completed":{"type":"boolean","title":"Registration Completed"},"has_completed_tour":{"type":"boolean","title":"Has Completed Tour","default":false},"auth_provider":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Auth Provider"},"apple_linked":{"type":"boolean","title":"Apple Linked","default":false}},"type":"object","required":["id","first_name","last_name","is_verified","member_since","registration_completed"],"title":"UserResponse"},"UserSubscriptionInfo":{"properties":{"user_id":{"type":"integer","title":"User Id"},"first_name":{"type":"string","title":"First Name"},"last_name":{"type":"string","title":"Last Name"},"full_name":{"type":"string","title":"Full Name"},"mobile_number":{"type":"string","title":"Mobile Number"},"phone_country_code":{"type":"string","title":"Phone Country Code"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email"},"has_subscription":{"type":"boolean","title":"Has Subscription"},"plan_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Plan Name"},"plan_display_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Plan Display Name"},"subscription_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Subscription Status"},"subscription_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Subscription Id"},"scans_used_this_month":{"type":"integer","title":"Scans Used This Month"},"is_premium":{"type":"boolean","title":"Is Premium"}},"type":"object","required":["user_id","first_name","last_name","full_name","mobile_number","phone_country_code","email","has_subscription","plan_name","plan_display_name","subscription_status","subscription_id","scans_used_this_month","is_premium"],"title":"UserSubscriptionInfo"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"ValueBases":{"properties":{"currency":{"type":"string","title":"Currency","default":"USD"},"primary":{"type":"string","title":"Primary","default":"retail_replacement"},"derivation":{"type":"string","title":"Derivation","default":"ratio"},"bases":{"additionalProperties":{"$ref":"#/components/schemas/ValueBasis"},"type":"object","title":"Bases"}},"type":"object","required":["bases"],"title":"ValueBases","description":"Retail replacement / fair market / resale for one piece [LNK-VALBASIS].\n\nAdditive and optional: pre-2.0.48 clients never read it and keep\nrendering estimated_value.best exactly as before."},"ValueBasis":{"properties":{"label":{"type":"string","title":"Label"},"best":{"type":"number","title":"Best"},"range_min":{"type":"number","title":"Range Min"},"range_max":{"type":"number","title":"Range Max"},"source":{"type":"string","title":"Source","default":"derived"},"multiple":{"type":"number","title":"Multiple","default":1.0},"note":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Note"}},"type":"object","required":["label","best","range_min","range_max"],"title":"ValueBasis","description":"One valuation basis [LNK-VALBASIS]."},"ValueBreakdownV2":{"properties":{"currency":{"const":"USD","title":"Currency","default":"USD"},"hero_amount":{"type":"number","minimum":0.0,"title":"Hero Amount"},"hero_range_min":{"type":"number","minimum":0.0,"title":"Hero Range Min"},"hero_range_max":{"type":"number","minimum":0.0,"title":"Hero Range Max"},"tier_1":{"$ref":"#/components/schemas/ValueTier1"},"tier_2":{"$ref":"#/components/schemas/ValueTier2"},"tier_3":{"$ref":"#/components/schemas/ValueTier3"},"estimated_piece_value":{"type":"number","minimum":0.0,"title":"Estimated Piece Value"},"approximate_retail_price":{"type":"number","minimum":0.0,"title":"Approximate Retail Price"},"headline_basis":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Headline Basis"}},"type":"object","required":["hero_amount","hero_range_min","hero_range_max","tier_1","tier_2","tier_3","estimated_piece_value","approximate_retail_price"],"title":"ValueBreakdownV2","description":"Three-tier value breakdown (DERIVED for back-compat).\n\nHybrid pipeline (LNK-IOP) replaced the model's structured tier\noutput with a lean `estimated_value` range. scan_client.py\nderives this `value` shape from `estimated_value` so older mobile\nclients reading `value.hero_amount` continue to work.\n\nTier 1 and Tier 2 are stubs ($0, empty arrays) in derived output.\nTier 3 carries the full estimated value. hero_amount equals\nestimated_value.best.\n\nThe previous hard validator (hero == tier_1 + tier_2 + tier_3) was\nremoved because the model no longer emits tier subtotals — derivation\nis mechanical, validation would always pass trivially."},"ValueHistoryPoint":{"properties":{"date":{"type":"string","title":"Date"},"value":{"type":"number","title":"Value"}},"type":"object","required":["date","value"],"title":"ValueHistoryPoint"},"ValueMetalLine":{"properties":{"type":{"type":"string","title":"Type"},"weight":{"type":"string","title":"Weight"},"rate":{"type":"string","title":"Rate"},"value":{"type":"number","minimum":0.0,"title":"Value"}},"type":"object","required":["type","weight","rate","value"],"title":"ValueMetalLine"},"ValueStoneLine":{"properties":{"description":{"type":"string","title":"Description"},"value":{"type":"number","minimum":0.0,"title":"Value"}},"type":"object","required":["description","value"],"title":"ValueStoneLine"},"ValueTier1":{"properties":{"label":{"type":"string","title":"Label","default":"Raw Value"},"metals":{"items":{"$ref":"#/components/schemas/ValueMetalLine"},"type":"array","title":"Metals"},"stones":{"items":{"$ref":"#/components/schemas/ValueStoneLine"},"type":"array","title":"Stones"},"subtotal":{"type":"number","minimum":0.0,"title":"Subtotal"}},"type":"object","required":["subtotal"],"title":"ValueTier1"},"ValueTier2":{"properties":{"label":{"type":"string","title":"Label","default":"Make Value"},"items":{"items":{"$ref":"#/components/schemas/ValueTier2Item"},"type":"array","title":"Items"},"subtotal":{"type":"number","minimum":0.0,"title":"Subtotal"}},"type":"object","required":["subtotal"],"title":"ValueTier2"},"ValueTier2Item":{"properties":{"description":{"type":"string","title":"Description"},"value":{"type":"number","minimum":0.0,"title":"Value"}},"type":"object","required":["description","value"],"title":"ValueTier2Item"},"ValueTier3":{"properties":{"label":{"type":"string","title":"Label","default":"Market Value"},"description":{"type":"string","title":"Description"},"value":{"type":"number","minimum":0.0,"title":"Value"}},"type":"object","required":["description","value"],"title":"ValueTier3"},"VarietyCard":{"properties":{"variety":{"type":"string","title":"Variety"},"index_value":{"type":"number","title":"Index Value"},"change_1d_pct":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Change 1D Pct"},"change_7d_pct":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Change 7D Pct"},"change_30d_pct":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Change 30D Pct"},"confidence_tier":{"type":"string","title":"Confidence Tier","default":"moderate"},"explanation_headline":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Explanation Headline"},"sparkline_7d":{"items":{"type":"number"},"type":"array","title":"Sparkline 7D","default":[]},"owned_count":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Owned Count"},"owned_est_value":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Owned Est Value"},"is_watched":{"type":"boolean","title":"Is Watched","default":false},"image_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Image Url"},"tier":{"type":"string","title":"Tier","default":"deep"}},"type":"object","required":["variety","index_value"],"title":"VarietyCard"},"VarietyIndexBlock":{"properties":{"index_value":{"type":"number","title":"Index Value"},"change_1d_pct":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Change 1D Pct"},"change_7d_pct":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Change 7D Pct"},"change_30d_pct":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Change 30D Pct"},"change_1y_pct":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Change 1Y Pct"},"confidence_tier":{"type":"string","title":"Confidence Tier","default":"moderate"},"explanation_headline":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Explanation Headline"},"as_of":{"type":"string","title":"As Of"}},"type":"object","required":["index_value","as_of"],"title":"VarietyIndexBlock"},"VarietyListingItem":{"properties":{"title":{"type":"string","title":"Title"},"price":{"type":"number","title":"Price"},"carat":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Carat"},"source":{"type":"string","title":"Source"},"observed_at":{"type":"string","title":"Observed At"}},"type":"object","required":["title","price","source","observed_at"],"title":"VarietyListingItem"},"VarietyListingsResponse":{"properties":{"variety":{"type":"string","title":"Variety"},"items":{"items":{"$ref":"#/components/schemas/VarietyListingItem"},"type":"array","title":"Items"}},"type":"object","required":["variety","items"],"title":"VarietyListingsResponse"},"VarietyPageResponse":{"properties":{"index_method":{"type":"string","title":"Index Method","default":"legacy_modeled_reference"},"verified_listing_count":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Verified Listing Count"},"variety":{"type":"string","title":"Variety"},"tier":{"type":"string","title":"Tier","default":"deep"},"image_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Image Url"},"index":{"$ref":"#/components/schemas/VarietyIndexBlock"},"mark":{"allOf":[{"$ref":"#/components/schemas/MarkBlock"}],"default":{"bands":[]}},"asks":{"anyOf":[{"$ref":"#/components/schemas/AsksBlock"},{"type":"null"}]},"history_periods":{"items":{"type":"string"},"type":"array","title":"History Periods","default":[]},"signals":{"$ref":"#/components/schemas/IndexMoversResponse"},"ladder":{"items":{"$ref":"#/components/schemas/LadderBand"},"type":"array","title":"Ladder","default":[]},"comps":{"allOf":[{"$ref":"#/components/schemas/CompsBlock"}],"default":{"total":0,"items":[]}},"news":{"items":{"$ref":"#/components/schemas/NewsItemV2"},"type":"array","title":"News","default":[]},"species_content":{"anyOf":[{"$ref":"#/components/schemas/SpeciesContentResponse"},{"type":"null"}]},"supply":{"anyOf":[{"$ref":"#/components/schemas/SupplyBlock"},{"type":"null"}]},"market_data":{"anyOf":[{"$ref":"#/components/schemas/GemstoneMarketDetailResponse"},{"type":"null"}]},"distributions":{"anyOf":[{"$ref":"#/components/schemas/DistributionsBlock"},{"type":"null"}]},"your_position":{"anyOf":[{"$ref":"#/components/schemas/YourPosition"},{"type":"null"}]}},"type":"object","required":["variety","index","signals"],"title":"VarietyPageResponse"},"VerdictIn":{"properties":{"verdict":{"type":"string","enum":["keep","drop"],"title":"Verdict"},"reviewer":{"type":"string","maxLength":64,"minLength":1,"title":"Reviewer"},"note":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Note"}},"type":"object","required":["verdict","reviewer"],"title":"VerdictIn"},"VerifyEmailOTPRequest":{"properties":{"email":{"type":"string","title":"Email","description":"Email address"},"otp_code":{"type":"string","title":"Otp Code","description":"6-digit OTP sent to the email"},"gemstone_ids":{"anyOf":[{"items":{"type":"integer"},"type":"array"},{"type":"null"}],"title":"Gemstone Ids","description":"Optional list of anonymous gemstone IDs to link to the user"},"promo_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Promo Code","description":"Optional promo code to redeem on signup (LNK-PROMO)"}},"type":"object","required":["email","otp_code"],"title":"VerifyEmailOTPRequest"},"VerifyOTPRequest":{"properties":{"mobile_number":{"type":"string","title":"Mobile Number","description":"Full phone number with country code (e.g., '+911234567890')"},"phone_country_code":{"type":"string","title":"Phone Country Code","description":"Country code (e.g., '+91')"},"otp_code":{"type":"string","title":"Otp Code","description":"6-digit OTP sent to the user's mobile number"},"gemstone_ids":{"anyOf":[{"items":{"type":"integer"},"type":"array"},{"type":"null"}],"title":"Gemstone Ids","description":"Optional list of IDs of gemstones uploaded anonymously. These will be attached to the user after verification."}},"type":"object","required":["mobile_number","phone_country_code","otp_code"],"title":"VerifyOTPRequest"},"VersionGateResponse":{"properties":{"ios_min_version":{"type":"string","title":"Ios Min Version"},"android_min_version":{"type":"string","title":"Android Min Version"},"latest_version":{"type":"string","title":"Latest Version"},"ios_store_url":{"type":"string","title":"Ios Store Url"},"android_store_url":{"type":"string","title":"Android Store Url"},"message":{"type":"string","title":"Message"}},"type":"object","required":["ios_min_version","android_min_version","latest_version","ios_store_url","android_store_url","message"],"title":"VersionGateResponse"},"VoiceNoteUploadResponse":{"properties":{"id":{"type":"integer","title":"Id"},"prospect_id":{"type":"integer","title":"Prospect Id"},"job_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Job Id"},"status":{"type":"string","title":"Status"}},"type":"object","required":["id","prospect_id","status"],"title":"VoiceNoteUploadResponse","description":"After iOS Shortcut / admin uploads a voice note blob."},"VoteResponse":{"properties":{"entry_id":{"type":"integer","title":"Entry Id"},"vote_count":{"type":"integer","title":"Vote Count"},"has_voted":{"type":"boolean","title":"Has Voted"}},"type":"object","required":["entry_id","vote_count","has_voted"],"title":"VoteResponse"},"VsMarketBlock":{"properties":{"collection_change_pct_7d":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Collection Change Pct 7D"},"market_change_pct_7d":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Market Change Pct 7D"}},"type":"object","title":"VsMarketBlock"},"WatchlistAddRequest":{"properties":{"variety":{"type":"string","title":"Variety"}},"type":"object","required":["variety"],"title":"WatchlistAddRequest"},"WatchlistDeleteResponse":{"properties":{"success":{"type":"boolean","title":"Success"},"variety":{"type":"string","title":"Variety"}},"type":"object","required":["success","variety"],"title":"WatchlistDeleteResponse"},"WatchlistItemResponse":{"properties":{"variety":{"type":"string","title":"Variety"},"index_value":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Index Value"},"change_pct_7d":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Change Pct 7D"},"watched_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Watched At"}},"type":"object","required":["variety"],"title":"WatchlistItemResponse"},"WatchlistResponse":{"properties":{"items":{"items":{"$ref":"#/components/schemas/WatchlistItemResponse"},"type":"array","title":"Items"}},"type":"object","required":["items"],"title":"WatchlistResponse"},"WeightRangePrice":{"properties":{"weight_min":{"type":"number","title":"Weight Min"},"weight_max":{"type":"number","title":"Weight Max"},"price_per_carat_low":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Price Per Carat Low"},"price_per_carat_fair":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Price Per Carat Fair"},"price_per_carat_avg":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Price Per Carat Avg"},"price_per_carat_good":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Price Per Carat Good"},"price_per_carat_excellent":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Price Per Carat Excellent"},"sample_size":{"type":"integer","title":"Sample Size","default":0}},"type":"object","required":["weight_min","weight_max"],"title":"WeightRangePrice"},"YourPosition":{"properties":{"owned_count":{"type":"integer","title":"Owned Count"},"est_value":{"type":"number","title":"Est Value"},"gems":{"items":{"$ref":"#/components/schemas/PositionGem"},"type":"array","title":"Gems","default":[]}},"type":"object","required":["owned_count","est_value"],"title":"YourPosition"},"app__schemas__chart_data__MoversBlock":{"properties":{"gainers":{"items":{"$ref":"#/components/schemas/MoverItem"},"type":"array","title":"Gainers"},"losers":{"items":{"$ref":"#/components/schemas/MoverItem"},"type":"array","title":"Losers"}},"type":"object","required":["gainers","losers"],"title":"MoversBlock"},"app__schemas__gemstone__About":{"properties":{"history_and_lore":{"type":"string","title":"History And Lore"},"cultural_significance":{"type":"string","title":"Cultural Significance"}},"type":"object","required":["history_and_lore","cultural_significance"],"title":"About","description":"Educational content about the gemstone"},"app__schemas__gemstone__MarketInsights":{"properties":{"trend":{"type":"string","title":"Trend"},"rarity":{"type":"string","title":"Rarity"},"supply":{"type":"string","title":"Supply"}},"type":"object","required":["trend","rarity","supply"],"title":"MarketInsights","description":"Market-level insights"},"app__schemas__market_v2__MoversBlock":{"properties":{"gainers":{"items":{"$ref":"#/components/schemas/VarietyCard"},"type":"array","title":"Gainers","default":[]},"losers":{"items":{"$ref":"#/components/schemas/VarietyCard"},"type":"array","title":"Losers","default":[]}},"type":"object","title":"MoversBlock"},"app__schemas__scan_v2__About":{"properties":{"history_and_lore":{"type":"string","minLength":60,"title":"History And Lore"},"cultural_significance":{"type":"string","minLength":60,"title":"Cultural Significance"}},"type":"object","required":["history_and_lore","cultural_significance"],"title":"About"},"app__schemas__scan_v2__MarketInsights":{"properties":{"trend":{"type":"string","enum":["Rising","Stable","Declining"],"title":"Trend"},"rarity":{"type":"string","enum":["Extremely Rare","Rare","Moderately Rare","Common"],"title":"Rarity"},"supply":{"type":"string","enum":["Limited","Moderate","Abundant"],"title":"Supply"}},"type":"object","required":["trend","rarity","supply"],"title":"MarketInsights"}},"securitySchemes":{"HTTPBearer":{"type":"http","scheme":"bearer"}}}}