> For the complete documentation index, see [llms.txt](https://docs.amigo.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.amigo.ai/api-reference/readme/platform/settings.md).

# Settings

## Get retention policy

> Get the workspace retention policy.\
> \
> Returns HIPAA-compliant defaults (2190 days / 6 years) for any field\
> not explicitly configured. Advisory in v1 — no automated deletion.\
> \
> Permissions: authenticated (any role).

```json
{"openapi":"3.1.0","info":{"title":"Platform API","version":"1.0.0"},"servers":[{"url":"https://api.platform.amigo.ai","description":"Production"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","description":"API key issued via `POST /v1/{workspace_id}/api-keys`. Pass the returned `api_key` value as a Bearer token."}},"schemas":{"RetentionPolicyResponse":{"properties":{"call_recordings_days":{"type":"integer","title":"Call Recordings Days"},"call_transcripts_days":{"type":"integer","title":"Call Transcripts Days"},"audit_log_days":{"type":"integer","title":"Audit Log Days"},"world_events_days":{"type":"integer","title":"World Events Days"},"phi_data_days":{"type":"integer","title":"Phi Data Days"},"legal_hold":{"type":"boolean","title":"Legal Hold"},"legal_hold_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Legal Hold Reason"}},"type":"object","required":["call_recordings_days","call_transcripts_days","audit_log_days","world_events_days","phi_data_days","legal_hold"],"title":"RetentionPolicyResponse"}}},"paths":{"/v1/{workspace_id}/settings/retention":{"get":{"tags":["Settings"],"summary":"Get retention policy","description":"Get the workspace retention policy.\n\nReturns HIPAA-compliant defaults (2190 days / 6 years) for any field\nnot explicitly configured. Advisory in v1 — no automated deletion.\n\nPermissions: authenticated (any role).","operationId":"get-retention-policy","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionPolicyResponse"}}}},"429":{"description":"Rate limited"}},"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Workspace Id"}}]}}}}
```

## Update retention policy

> Update the workspace retention policy.\
> \
> Partial updates supported — only provided fields are changed.\
> Advisory in v1: policy is stored and displayed but no automated\
> deletion is performed. Legal hold overrides all retention.\
> \
> Permissions: admin, owner (\`\`Workspace.update\`\`).

```json
{"openapi":"3.1.0","info":{"title":"Platform API","version":"1.0.0"},"servers":[{"url":"https://api.platform.amigo.ai","description":"Production"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","description":"API key issued via `POST /v1/{workspace_id}/api-keys`. Pass the returned `api_key` value as a Bearer token."}},"schemas":{"RetentionPolicyRequest":{"properties":{"call_recordings_days":{"anyOf":[{"type":"integer","maximum":36500,"minimum":365},{"type":"null"}],"title":"Call Recordings Days"},"call_transcripts_days":{"anyOf":[{"type":"integer","maximum":36500,"minimum":365},{"type":"null"}],"title":"Call Transcripts Days"},"audit_log_days":{"anyOf":[{"type":"integer","maximum":36500,"minimum":365},{"type":"null"}],"title":"Audit Log Days"},"world_events_days":{"anyOf":[{"type":"integer","maximum":36500,"minimum":365},{"type":"null"}],"title":"World Events Days"},"phi_data_days":{"anyOf":[{"type":"integer","maximum":36500,"minimum":365},{"type":"null"}],"title":"Phi Data Days"},"legal_hold":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Legal Hold"},"legal_hold_reason":{"anyOf":[{"$ref":"#/components/schemas/DescriptionString"},{"type":"null"}]}},"type":"object","title":"RetentionPolicyRequest"},"DescriptionString":{"type":"string","maxLength":2000},"RetentionPolicyResponse":{"properties":{"call_recordings_days":{"type":"integer","title":"Call Recordings Days"},"call_transcripts_days":{"type":"integer","title":"Call Transcripts Days"},"audit_log_days":{"type":"integer","title":"Audit Log Days"},"world_events_days":{"type":"integer","title":"World Events Days"},"phi_data_days":{"type":"integer","title":"Phi Data Days"},"legal_hold":{"type":"boolean","title":"Legal Hold"},"legal_hold_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Legal Hold Reason"}},"type":"object","required":["call_recordings_days","call_transcripts_days","audit_log_days","world_events_days","phi_data_days","legal_hold"],"title":"RetentionPolicyResponse"}}},"paths":{"/v1/{workspace_id}/settings/retention":{"put":{"tags":["Settings"],"summary":"Update retention policy","description":"Update the workspace retention policy.\n\nPartial updates supported — only provided fields are changed.\nAdvisory in v1: policy is stored and displayed but no automated\ndeletion is performed. Legal hold overrides all retention.\n\nPermissions: admin, owner (``Workspace.update``).","operationId":"update-retention-policy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionPolicyRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionPolicyResponse"}}}},"404":{"description":"Workspace not found"},"422":{"description":"Validation error"},"429":{"description":"Rate limited"}},"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Workspace Id"}}]}}}}
```

## Get gap scanner settings

> Get the workspace gap scanner settings.\
> \
> Returns defaults when not configured. Gap scanner is disabled by default.\
> \
> Permissions: authenticated (any role).

```json
{"openapi":"3.1.0","info":{"title":"Platform API","version":"1.0.0"},"servers":[{"url":"https://api.platform.amigo.ai","description":"Production"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","description":"API key issued via `POST /v1/{workspace_id}/api-keys`. Pass the returned `api_key` value as a Bearer token."}},"schemas":{"GapScannerSettingsResponse":{"properties":{"enabled":{"type":"boolean","title":"Enabled"},"scan_interval_seconds":{"type":"integer","title":"Scan Interval Seconds"},"appointment_lookahead_hours":{"type":"integer","title":"Appointment Lookahead Hours"},"cooldown_hours":{"type":"integer","title":"Cooldown Hours"},"max_surfaces_per_tick":{"type":"integer","title":"Max Surfaces Per Tick"},"max_pending_surfaces":{"type":"integer","title":"Max Pending Surfaces"},"min_completion_rate":{"type":"number","title":"Min Completion Rate"},"channel_optimization":{"type":"boolean","title":"Channel Optimization"},"requirements":{"items":{"$ref":"#/components/schemas/GapRequirement-Output"},"type":"array","title":"Requirements"}},"type":"object","required":["enabled","scan_interval_seconds","appointment_lookahead_hours","cooldown_hours","max_surfaces_per_tick","max_pending_surfaces","min_completion_rate","channel_optimization","requirements"],"title":"GapScannerSettingsResponse"},"GapRequirement-Output":{"properties":{"name":{"$ref":"#/components/schemas/NameString"},"entity_type":{"type":"string","const":"person","title":"Entity Type","default":"person"},"trigger":{"type":"string","enum":["upcoming_appointment","recent_interaction"],"title":"Trigger","default":"upcoming_appointment"},"required_fields":{"items":{"$ref":"#/components/schemas/GapRequiredField"},"type":"array","maxItems":50,"minItems":1,"title":"Required Fields"},"channel":{"$ref":"#/components/schemas/ChannelType","default":"email"},"priority":{"type":"string","enum":["low","normal","high"],"title":"Priority","default":"normal"},"surface_title":{"anyOf":[{"$ref":"#/components/schemas/NameString"},{"type":"null"}],"description":"Title for generated surfaces. Defaults to requirement name."},"surface_description":{"anyOf":[{"$ref":"#/components/schemas/DescriptionString"},{"type":"null"}]}},"type":"object","required":["name","required_fields"],"title":"GapRequirement","description":"A named gap detection rule."},"NameString":{"type":"string","maxLength":256,"minLength":1},"GapRequiredField":{"properties":{"path":{"type":"string","maxLength":256,"minLength":1,"title":"Path","description":"Dot-notation path into entity state"},"label":{"$ref":"#/components/schemas/NameString"},"field_type":{"$ref":"#/components/schemas/FieldType","default":"text"},"min_items":{"anyOf":[{"type":"integer","maximum":100,"minimum":0},{"type":"null"}],"title":"Min Items","description":"For list fields, minimum items required"}},"type":"object","required":["path","label"],"title":"GapRequiredField","description":"A field that must be present in entity state."},"FieldType":{"type":"string","enum":["text","textarea","date","phone","email","number","select","multiselect","checkbox","photo","signature","file","heading","info"],"title":"FieldType","description":"Input field types for surface data collection."},"ChannelType":{"type":"string","enum":["email","web","sms"],"title":"ChannelType","description":"Delivery channels for surfaces."},"DescriptionString":{"type":"string","maxLength":2000}}},"paths":{"/v1/{workspace_id}/settings/gap-scanner":{"get":{"tags":["Settings"],"summary":"Get gap scanner settings","description":"Get the workspace gap scanner settings.\n\nReturns defaults when not configured. Gap scanner is disabled by default.\n\nPermissions: authenticated (any role).","operationId":"get-gap-scanner-settings","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GapScannerSettingsResponse"}}}},"429":{"description":"Rate limited"}},"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Workspace Id"}}]}}}}
```

## Update gap scanner settings

> Update the workspace gap scanner settings.\
> \
> Partial updates supported — only provided fields are changed.\
> Requirements list is replaced entirely when provided (not merged).\
> \
> Permissions: admin, owner (enforced via \`\`Workspace.update\`\`, matching\
> the outreach-settings sibling).

```json
{"openapi":"3.1.0","info":{"title":"Platform API","version":"1.0.0"},"servers":[{"url":"https://api.platform.amigo.ai","description":"Production"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","description":"API key issued via `POST /v1/{workspace_id}/api-keys`. Pass the returned `api_key` value as a Bearer token."}},"schemas":{"GapScannerSettingsRequest":{"properties":{"enabled":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Enabled"},"scan_interval_seconds":{"anyOf":[{"type":"integer","maximum":86400,"minimum":60},{"type":"null"}],"title":"Scan Interval Seconds"},"appointment_lookahead_hours":{"anyOf":[{"type":"integer","maximum":720,"minimum":1},{"type":"null"}],"title":"Appointment Lookahead Hours"},"cooldown_hours":{"anyOf":[{"type":"integer","maximum":8760,"minimum":1},{"type":"null"}],"title":"Cooldown Hours"},"max_surfaces_per_tick":{"anyOf":[{"type":"integer","maximum":100,"minimum":1},{"type":"null"}],"title":"Max Surfaces Per Tick"},"max_pending_surfaces":{"anyOf":[{"type":"integer","maximum":50,"minimum":0},{"type":"null"}],"title":"Max Pending Surfaces","description":"Max non-terminal surfaces per entity (0 = disabled)"},"min_completion_rate":{"anyOf":[{"type":"number","maximum":1,"minimum":0},{"type":"null"}],"title":"Min Completion Rate","description":"Min historical completion rate to create new surfaces (0.0 = disabled)"},"channel_optimization":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Channel Optimization","description":"Use entity preferred channel over static requirement channel"},"requirements":{"anyOf":[{"items":{"$ref":"#/components/schemas/GapRequirement-Input"},"type":"array","maxItems":100},{"type":"null"}],"title":"Requirements"}},"type":"object","title":"GapScannerSettingsRequest"},"GapRequirement-Input":{"properties":{"name":{"$ref":"#/components/schemas/NameString"},"entity_type":{"type":"string","const":"person","title":"Entity Type","default":"person"},"trigger":{"type":"string","enum":["upcoming_appointment","recent_interaction"],"title":"Trigger","default":"upcoming_appointment"},"required_fields":{"items":{"$ref":"#/components/schemas/GapRequiredField"},"type":"array","maxItems":50,"minItems":1,"title":"Required Fields"},"channel":{"$ref":"#/components/schemas/ChannelType","default":"email"},"priority":{"type":"string","enum":["low","normal","high"],"title":"Priority","default":"normal"},"surface_title":{"anyOf":[{"$ref":"#/components/schemas/NameString"},{"type":"null"}],"description":"Title for generated surfaces. Defaults to requirement name."},"surface_description":{"anyOf":[{"$ref":"#/components/schemas/DescriptionString"},{"type":"null"}]}},"type":"object","required":["name","required_fields"],"title":"GapRequirement","description":"A named gap detection rule."},"NameString":{"type":"string","maxLength":256,"minLength":1},"GapRequiredField":{"properties":{"path":{"type":"string","maxLength":256,"minLength":1,"title":"Path","description":"Dot-notation path into entity state"},"label":{"$ref":"#/components/schemas/NameString"},"field_type":{"$ref":"#/components/schemas/FieldType","default":"text"},"min_items":{"anyOf":[{"type":"integer","maximum":100,"minimum":0},{"type":"null"}],"title":"Min Items","description":"For list fields, minimum items required"}},"type":"object","required":["path","label"],"title":"GapRequiredField","description":"A field that must be present in entity state."},"FieldType":{"type":"string","enum":["text","textarea","date","phone","email","number","select","multiselect","checkbox","photo","signature","file","heading","info"],"title":"FieldType","description":"Input field types for surface data collection."},"ChannelType":{"type":"string","enum":["email","web","sms"],"title":"ChannelType","description":"Delivery channels for surfaces."},"DescriptionString":{"type":"string","maxLength":2000},"GapScannerSettingsResponse":{"properties":{"enabled":{"type":"boolean","title":"Enabled"},"scan_interval_seconds":{"type":"integer","title":"Scan Interval Seconds"},"appointment_lookahead_hours":{"type":"integer","title":"Appointment Lookahead Hours"},"cooldown_hours":{"type":"integer","title":"Cooldown Hours"},"max_surfaces_per_tick":{"type":"integer","title":"Max Surfaces Per Tick"},"max_pending_surfaces":{"type":"integer","title":"Max Pending Surfaces"},"min_completion_rate":{"type":"number","title":"Min Completion Rate"},"channel_optimization":{"type":"boolean","title":"Channel Optimization"},"requirements":{"items":{"$ref":"#/components/schemas/GapRequirement-Output"},"type":"array","title":"Requirements"}},"type":"object","required":["enabled","scan_interval_seconds","appointment_lookahead_hours","cooldown_hours","max_surfaces_per_tick","max_pending_surfaces","min_completion_rate","channel_optimization","requirements"],"title":"GapScannerSettingsResponse"},"GapRequirement-Output":{"properties":{"name":{"$ref":"#/components/schemas/NameString"},"entity_type":{"type":"string","const":"person","title":"Entity Type","default":"person"},"trigger":{"type":"string","enum":["upcoming_appointment","recent_interaction"],"title":"Trigger","default":"upcoming_appointment"},"required_fields":{"items":{"$ref":"#/components/schemas/GapRequiredField"},"type":"array","maxItems":50,"minItems":1,"title":"Required Fields"},"channel":{"$ref":"#/components/schemas/ChannelType","default":"email"},"priority":{"type":"string","enum":["low","normal","high"],"title":"Priority","default":"normal"},"surface_title":{"anyOf":[{"$ref":"#/components/schemas/NameString"},{"type":"null"}],"description":"Title for generated surfaces. Defaults to requirement name."},"surface_description":{"anyOf":[{"$ref":"#/components/schemas/DescriptionString"},{"type":"null"}]}},"type":"object","required":["name","required_fields"],"title":"GapRequirement","description":"A named gap detection rule."}}},"paths":{"/v1/{workspace_id}/settings/gap-scanner":{"put":{"tags":["Settings"],"summary":"Update gap scanner settings","description":"Update the workspace gap scanner settings.\n\nPartial updates supported — only provided fields are changed.\nRequirements list is replaced entirely when provided (not merged).\n\nPermissions: admin, owner (enforced via ``Workspace.update``, matching\nthe outreach-settings sibling).","operationId":"update-gap-scanner-settings","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GapScannerSettingsRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GapScannerSettingsResponse"}}}},"404":{"description":"Workspace not found"},"422":{"description":"Validation error"},"429":{"description":"Rate limited"}},"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Workspace Id"}}]}}}}
```

## Preview gap detection (dry run)

> Dry-run gap detection — returns entities with missing fields without creating surfaces.\
> \
> Proxies to connector-runner /internal/gap-scanner/preview.\
> \
> Permissions: admin, owner (enforced via \`\`Workspace.update\`\`).

```json
{"openapi":"3.1.0","info":{"title":"Platform API","version":"1.0.0"},"servers":[{"url":"https://api.platform.amigo.ai","description":"Production"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","description":"API key issued via `POST /v1/{workspace_id}/api-keys`. Pass the returned `api_key` value as a Bearer token."}},"schemas":{"GapScannerPreviewRequest":{"properties":{"limit":{"type":"integer","maximum":200,"minimum":1,"title":"Limit","default":50}},"type":"object","title":"GapScannerPreviewRequest"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"paths":{"/v1/{workspace_id}/settings/gap-scanner/preview":{"post":{"tags":["Settings"],"summary":"Preview gap detection (dry run)","description":"Dry-run gap detection — returns entities with missing fields without creating surfaces.\n\nProxies to connector-runner /internal/gap-scanner/preview.\n\nPermissions: admin, owner (enforced via ``Workspace.update``).","operationId":"gap-scanner-preview","requestBody":{"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/GapScannerPreviewRequest"},{"type":"null"}],"title":"Body"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Gap-Scanner-Preview"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"429":{"description":"Rate limited"},"503":{"description":"Connector runner unavailable"}},"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Workspace Id"}}]}}}}
```

## Trigger one scan tick

> Trigger one scan tick immediately — creates surfaces for detected gaps.\
> \
> Proxies to connector-runner /internal/gap-scanner/scan.\
> \
> Permissions: admin, owner (enforced via \`\`Workspace.update\`\` — this\
> creates patient-facing surfaces, so it must not be reachable below\
> admin tier).

```json
{"openapi":"3.1.0","info":{"title":"Platform API","version":"1.0.0"},"servers":[{"url":"https://api.platform.amigo.ai","description":"Production"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","description":"API key issued via `POST /v1/{workspace_id}/api-keys`. Pass the returned `api_key` value as a Bearer token."}}},"paths":{"/v1/{workspace_id}/settings/gap-scanner/scan":{"post":{"tags":["Settings"],"summary":"Trigger one scan tick","description":"Trigger one scan tick immediately — creates surfaces for detected gaps.\n\nProxies to connector-runner /internal/gap-scanner/scan.\n\nPermissions: admin, owner (enforced via ``Workspace.update`` — this\ncreates patient-facing surfaces, so it must not be reachable below\nadmin tier).","operationId":"gap-scanner-scan","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Gap-Scanner-Scan"}}}},"429":{"description":"Rate limited"},"503":{"description":"Connector runner unavailable"}},"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Workspace Id"}}]}}}}
```

## Get metric definitions

> Get the workspace metric definitions.\
> \
> Returns built-in defaults when not configured.\
> \
> Permissions: authenticated (any role).

```json
{"openapi":"3.1.0","info":{"title":"Platform API","version":"1.0.0"},"servers":[{"url":"https://api.platform.amigo.ai","description":"Production"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","description":"API key issued via `POST /v1/{workspace_id}/api-keys`. Pass the returned `api_key` value as a Bearer token."}},"schemas":{"MetricSettingsResponse":{"properties":{"definitions":{"items":{"$ref":"#/components/schemas/MetricDefinition"},"type":"array","title":"Definitions"}},"type":"object","required":["definitions"],"title":"MetricSettingsResponse"},"MetricDefinition":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"key":{"type":"string","maxLength":64,"minLength":1,"pattern":"^[a-z][a-z0-9_]*$","title":"Key","description":"Lowercase slug used as metric key (e.g. 'voice_quality_score')"},"name":{"$ref":"#/components/schemas/NameString"},"description":{"anyOf":[{"$ref":"#/components/schemas/DescriptionString"},{"type":"null"}]},"metric_type":{"type":"string","enum":["numerical","categorical","boolean"],"title":"Metric Type"},"latency_tier":{"type":"string","enum":["streaming","near_realtime","batch"],"title":"Latency Tier","description":"'streaming' — seconds-latency via ZeroBus streaming ingestion (continuous pipeline). 'near_realtime' — minutes-latency via triggered pipeline refresh. 'batch' — hourly/daily scheduled refresh (default, cheapest).","default":"batch"},"period_granularity":{"type":"string","enum":["hourly","daily"],"title":"Period Granularity","description":"'hourly' — one row per workspace per hour. Use for near_realtime metrics where shift-level visibility matters (voice quality, latency). 'daily' — one row per workspace per day (default, cheapest).","default":"daily"},"source":{"type":"string","enum":["call_intelligence","world_events","surface_events","emotion_events","connector_events","zerobus_events","voice_judge_results","custom"],"title":"Source","description":"Source key for the producer that supplies this metric. Built-ins include 'call_intelligence', 'world_events', and 'surface_events'. Use 'custom' with custom_source_key for extension producers."},"custom_source_key":{"anyOf":[{"type":"string","maxLength":128,"minLength":1,"pattern":"^[a-z][a-z0-9_]*$"},{"type":"null"}],"title":"Custom Source Key","description":"Extension source key used only when source='custom'."},"event_types":{"items":{"type":"string"},"type":"array","maxItems":100,"minItems":1,"title":"Event Types","description":"Event types to scan (e.g. 'call.outcome', 'surface.submitted'). For call_intelligence source, use pseudo-types: 'call_intelligence.row'."},"source_filter":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Filter","description":"Optional SQL WHERE fragment for additional filtering (e.g. \"source = 'voice_agent'\"). Applied after event_type filter."},"extraction_mode":{"type":"string","enum":["static","ai_classify","ai_extract","ai_query","sql_expr"],"title":"Extraction Mode","description":"'static' — JSONB path extraction (fast, free). 'ai_classify' — AI classification into user-defined labels (free). 'ai_extract' — AI field extraction from text (free). 'ai_query' — LLM-powered extraction with custom prompt (uses model_tier). 'sql_expr' — Raw SQL expression for computed metrics.","default":"static"},"extract_path":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Extract Path","description":"JSON path for static extraction (e.g. `$.quality_score`, `$.risk_level`). For `call_intelligence` and `world_events`, single-segment paths resolve to typed columns when available and fall back to JSONB extraction otherwise. Used when `extraction_mode='static'`."},"ai_labels":{"anyOf":[{"items":{"type":"string"},"type":"array","maxItems":500},{"type":"null"}],"title":"Ai Labels","description":"Labels for ai_classify (categories) or ai_extract (field names). Required when extraction_mode='ai_classify' or 'ai_extract'. Examples: ['positive', 'negative', 'neutral'] or ['diagnosis', 'medication']."},"ai_schema":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Ai Schema","description":"Extraction schema for ai_extract. Required when extraction_mode='ai_extract'."},"ai_query_endpoint":{"anyOf":[{"type":"string","maxLength":256},{"type":"null"}],"title":"Ai Query Endpoint","description":"Model serving endpoint for ai_query. Optional — if omitted, platform resolves from model_tier automatically. Override for custom endpoints."},"ai_query_prompt":{"anyOf":[{"type":"string","maxLength":8000},{"type":"null"}],"title":"Ai Query Prompt","description":"Prompt template for ai_query. Use {data} placeholder for event data. Example: 'Classify this call transcript into one of: {labels}. Transcript: {data}'. Budgeted at 8KB to hold the full rubric + output spec for standard quality judges (longest authored rubric — conversational_naturalness — is ~5KB)."},"sql_expression":{"anyOf":[{"type":"string","maxLength":1000},{"type":"null"}],"title":"Sql Expression","description":"Raw SQL expression evaluated in pipeline context. Has access to all columns in the source table. Example: 'CASE WHEN duration_seconds > 120 THEN 1.0 ELSE 0.0 END'. Required when extraction_mode='sql_expr'."},"aggregation":{"type":"string","enum":["count","sum","avg","min","max","count_distinct","ratio","rate"],"title":"Aggregation","description":"How to aggregate extracted values per workspace per period. 'ratio' requires ratio_numerator_event and ratio_denominator_event. 'rate' computes count(true) / count(all) for boolean metrics.","default":"count"},"ratio_numerator_event":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ratio Numerator Event","description":"Event type for numerator when aggregation='ratio'."},"ratio_denominator_event":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ratio Denominator Event","description":"Event type for denominator when aggregation='ratio'."},"valid_range_min":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Valid Range Min","description":"Minimum valid value for numerical metrics. Pipeline drops values outside range."},"valid_range_max":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Valid Range Max","description":"Maximum valid value for numerical metrics."},"freshness_sla_minutes":{"type":"integer","maximum":1440,"minimum":5,"title":"Freshness Sla Minutes","description":"Max acceptable staleness in minutes before alerting. Default: 60 (1 hour).","default":60},"unit":{"anyOf":[{"type":"string","maxLength":32},{"type":"null"}],"title":"Unit","description":"Display unit (e.g. 'score', 'minutes', '%', 'count')."},"categories":{"anyOf":[{"items":{"type":"string"},"type":"array","maxItems":100},{"type":"null"}],"title":"Categories","description":"Allowed values for categorical metrics. Pipeline drops values not in this list when set."},"model_tier":{"type":"string","enum":["free","fast","balanced","max","custom"],"title":"Model Tier","description":"AI model tier for extraction quality/cost tradeoff. 'free' — platform managed models (ai_classify, ai_extract). 'fast' — optimized for simple classification, low latency. 'balanced' — quality scoring, moderate reasoning. 'max' — complex analysis, multi-step reasoning. 'custom' — use ai_query_endpoint directly. When extraction_mode='ai_query' and ai_query_endpoint is not set, platform resolves model_tier to the optimal model automatically.","default":"free"},"channel_scope":{"type":"string","enum":["all","voice","text","surface","inbound","outbound"],"title":"Channel Scope","description":"Business-logic channel filter. 'voice' — voice calls only. 'text' — SMS/text sessions. 'surface' — form submissions. 'inbound'/'outbound' — by direction. 'all' — no channel filter (default). Pipeline translates to appropriate source + event_type filters.","default":"all"},"applies_to_product_types":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Applies To Product Types","description":"Product types this metric applies to (matches service tags, e.g. 'scheduling', 'outbound', 'coaching', 'intake', 'triage', 'support'). When set, the metric only computes for calls belonging to services whose config.tags include one of these keys. When None (default), the metric applies to every service regardless of product type."},"prompt":{"anyOf":[{"type":"string","maxLength":4000},{"type":"null"}],"title":"Prompt","description":"Rubric prompt for LLM judge evaluation with {$.path} context variables. Each {$.path} reference is extracted from the entity's projected state and substituted before sending to ai_query. The prompt is both the evaluation criteria and the context specification."},"granularity":{"type":"string","enum":["aggregate","per_entity"],"title":"Granularity","description":"'aggregate' groups by (workspace, period) — one value per time bucket. 'per_entity' keeps entity_id — one value per entity (call, encounter). Judge metrics are typically per_entity. Computed metrics are typically aggregate.","default":"aggregate"},"active":{"type":"boolean","title":"Active","default":true},"builtin":{"type":"boolean","title":"Builtin","description":"True for platform-provided metrics (read-only key).","default":false}},"type":"object","required":["key","name","metric_type","source","event_types"],"title":"MetricDefinition","description":"A single metric definition — what to extract and how.\n\nTwo broad modes:\n- Built-in metrics: extraction is handled by hardcoded pipeline logic\n  (extract_path + aggregation). Shipped with every workspace.\n- Custom metrics: extraction uses AI functions or static JSONB paths.\n  Defined per-workspace via settings API.\n\nFrozen: builtins are process-wide singletons exposed via the\n``BUILTIN_METRICS`` list. A mutable list field (e.g.\n``applies_to_product_types``) could otherwise be mutated by one caller\nand leak into every subsequent call in the same process."},"NameString":{"type":"string","maxLength":256,"minLength":1},"DescriptionString":{"type":"string","maxLength":2000}}},"paths":{"/v1/{workspace_id}/settings/metrics":{"get":{"tags":["Settings"],"summary":"Get metric definitions","description":"Get the workspace metric definitions.\n\nReturns built-in defaults when not configured.\n\nPermissions: authenticated (any role).","operationId":"get-metric-settings","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricSettingsResponse"}}}},"429":{"description":"Rate limited"}},"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Workspace Id"}}]}}}}
```

## Update metric definitions

> Update the workspace metric definitions.\
> \
> Partial updates supported — only provided fields are changed.\
> The definitions list is replaced entirely when provided.\
> \
> Permissions: admin, owner.

```json
{"openapi":"3.1.0","info":{"title":"Platform API","version":"1.0.0"},"servers":[{"url":"https://api.platform.amigo.ai","description":"Production"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","description":"API key issued via `POST /v1/{workspace_id}/api-keys`. Pass the returned `api_key` value as a Bearer token."}},"schemas":{"MetricSettingsRequest":{"properties":{"definitions":{"anyOf":[{"items":{"$ref":"#/components/schemas/MetricDefinition"},"type":"array"},{"type":"null"}],"title":"Definitions"}},"type":"object","title":"MetricSettingsRequest","description":"Partial update — only provided fields are changed.\n\nThe definitions list is replaced entirely when provided.\nBuilt-in metrics can be deactivated (active=false) or have their\nfreshness_sla_minutes changed, but their key cannot be reused\nfor custom metrics."},"MetricDefinition":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"key":{"type":"string","maxLength":64,"minLength":1,"pattern":"^[a-z][a-z0-9_]*$","title":"Key","description":"Lowercase slug used as metric key (e.g. 'voice_quality_score')"},"name":{"$ref":"#/components/schemas/NameString"},"description":{"anyOf":[{"$ref":"#/components/schemas/DescriptionString"},{"type":"null"}]},"metric_type":{"type":"string","enum":["numerical","categorical","boolean"],"title":"Metric Type"},"latency_tier":{"type":"string","enum":["streaming","near_realtime","batch"],"title":"Latency Tier","description":"'streaming' — seconds-latency via ZeroBus streaming ingestion (continuous pipeline). 'near_realtime' — minutes-latency via triggered pipeline refresh. 'batch' — hourly/daily scheduled refresh (default, cheapest).","default":"batch"},"period_granularity":{"type":"string","enum":["hourly","daily"],"title":"Period Granularity","description":"'hourly' — one row per workspace per hour. Use for near_realtime metrics where shift-level visibility matters (voice quality, latency). 'daily' — one row per workspace per day (default, cheapest).","default":"daily"},"source":{"type":"string","enum":["call_intelligence","world_events","surface_events","emotion_events","connector_events","zerobus_events","voice_judge_results","custom"],"title":"Source","description":"Source key for the producer that supplies this metric. Built-ins include 'call_intelligence', 'world_events', and 'surface_events'. Use 'custom' with custom_source_key for extension producers."},"custom_source_key":{"anyOf":[{"type":"string","maxLength":128,"minLength":1,"pattern":"^[a-z][a-z0-9_]*$"},{"type":"null"}],"title":"Custom Source Key","description":"Extension source key used only when source='custom'."},"event_types":{"items":{"type":"string"},"type":"array","maxItems":100,"minItems":1,"title":"Event Types","description":"Event types to scan (e.g. 'call.outcome', 'surface.submitted'). For call_intelligence source, use pseudo-types: 'call_intelligence.row'."},"source_filter":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Filter","description":"Optional SQL WHERE fragment for additional filtering (e.g. \"source = 'voice_agent'\"). Applied after event_type filter."},"extraction_mode":{"type":"string","enum":["static","ai_classify","ai_extract","ai_query","sql_expr"],"title":"Extraction Mode","description":"'static' — JSONB path extraction (fast, free). 'ai_classify' — AI classification into user-defined labels (free). 'ai_extract' — AI field extraction from text (free). 'ai_query' — LLM-powered extraction with custom prompt (uses model_tier). 'sql_expr' — Raw SQL expression for computed metrics.","default":"static"},"extract_path":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Extract Path","description":"JSON path for static extraction (e.g. `$.quality_score`, `$.risk_level`). For `call_intelligence` and `world_events`, single-segment paths resolve to typed columns when available and fall back to JSONB extraction otherwise. Used when `extraction_mode='static'`."},"ai_labels":{"anyOf":[{"items":{"type":"string"},"type":"array","maxItems":500},{"type":"null"}],"title":"Ai Labels","description":"Labels for ai_classify (categories) or ai_extract (field names). Required when extraction_mode='ai_classify' or 'ai_extract'. Examples: ['positive', 'negative', 'neutral'] or ['diagnosis', 'medication']."},"ai_schema":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Ai Schema","description":"Extraction schema for ai_extract. Required when extraction_mode='ai_extract'."},"ai_query_endpoint":{"anyOf":[{"type":"string","maxLength":256},{"type":"null"}],"title":"Ai Query Endpoint","description":"Model serving endpoint for ai_query. Optional — if omitted, platform resolves from model_tier automatically. Override for custom endpoints."},"ai_query_prompt":{"anyOf":[{"type":"string","maxLength":8000},{"type":"null"}],"title":"Ai Query Prompt","description":"Prompt template for ai_query. Use {data} placeholder for event data. Example: 'Classify this call transcript into one of: {labels}. Transcript: {data}'. Budgeted at 8KB to hold the full rubric + output spec for standard quality judges (longest authored rubric — conversational_naturalness — is ~5KB)."},"sql_expression":{"anyOf":[{"type":"string","maxLength":1000},{"type":"null"}],"title":"Sql Expression","description":"Raw SQL expression evaluated in pipeline context. Has access to all columns in the source table. Example: 'CASE WHEN duration_seconds > 120 THEN 1.0 ELSE 0.0 END'. Required when extraction_mode='sql_expr'."},"aggregation":{"type":"string","enum":["count","sum","avg","min","max","count_distinct","ratio","rate"],"title":"Aggregation","description":"How to aggregate extracted values per workspace per period. 'ratio' requires ratio_numerator_event and ratio_denominator_event. 'rate' computes count(true) / count(all) for boolean metrics.","default":"count"},"ratio_numerator_event":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ratio Numerator Event","description":"Event type for numerator when aggregation='ratio'."},"ratio_denominator_event":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ratio Denominator Event","description":"Event type for denominator when aggregation='ratio'."},"valid_range_min":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Valid Range Min","description":"Minimum valid value for numerical metrics. Pipeline drops values outside range."},"valid_range_max":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Valid Range Max","description":"Maximum valid value for numerical metrics."},"freshness_sla_minutes":{"type":"integer","maximum":1440,"minimum":5,"title":"Freshness Sla Minutes","description":"Max acceptable staleness in minutes before alerting. Default: 60 (1 hour).","default":60},"unit":{"anyOf":[{"type":"string","maxLength":32},{"type":"null"}],"title":"Unit","description":"Display unit (e.g. 'score', 'minutes', '%', 'count')."},"categories":{"anyOf":[{"items":{"type":"string"},"type":"array","maxItems":100},{"type":"null"}],"title":"Categories","description":"Allowed values for categorical metrics. Pipeline drops values not in this list when set."},"model_tier":{"type":"string","enum":["free","fast","balanced","max","custom"],"title":"Model Tier","description":"AI model tier for extraction quality/cost tradeoff. 'free' — platform managed models (ai_classify, ai_extract). 'fast' — optimized for simple classification, low latency. 'balanced' — quality scoring, moderate reasoning. 'max' — complex analysis, multi-step reasoning. 'custom' — use ai_query_endpoint directly. When extraction_mode='ai_query' and ai_query_endpoint is not set, platform resolves model_tier to the optimal model automatically.","default":"free"},"channel_scope":{"type":"string","enum":["all","voice","text","surface","inbound","outbound"],"title":"Channel Scope","description":"Business-logic channel filter. 'voice' — voice calls only. 'text' — SMS/text sessions. 'surface' — form submissions. 'inbound'/'outbound' — by direction. 'all' — no channel filter (default). Pipeline translates to appropriate source + event_type filters.","default":"all"},"applies_to_product_types":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Applies To Product Types","description":"Product types this metric applies to (matches service tags, e.g. 'scheduling', 'outbound', 'coaching', 'intake', 'triage', 'support'). When set, the metric only computes for calls belonging to services whose config.tags include one of these keys. When None (default), the metric applies to every service regardless of product type."},"prompt":{"anyOf":[{"type":"string","maxLength":4000},{"type":"null"}],"title":"Prompt","description":"Rubric prompt for LLM judge evaluation with {$.path} context variables. Each {$.path} reference is extracted from the entity's projected state and substituted before sending to ai_query. The prompt is both the evaluation criteria and the context specification."},"granularity":{"type":"string","enum":["aggregate","per_entity"],"title":"Granularity","description":"'aggregate' groups by (workspace, period) — one value per time bucket. 'per_entity' keeps entity_id — one value per entity (call, encounter). Judge metrics are typically per_entity. Computed metrics are typically aggregate.","default":"aggregate"},"active":{"type":"boolean","title":"Active","default":true},"builtin":{"type":"boolean","title":"Builtin","description":"True for platform-provided metrics (read-only key).","default":false}},"type":"object","required":["key","name","metric_type","source","event_types"],"title":"MetricDefinition","description":"A single metric definition — what to extract and how.\n\nTwo broad modes:\n- Built-in metrics: extraction is handled by hardcoded pipeline logic\n  (extract_path + aggregation). Shipped with every workspace.\n- Custom metrics: extraction uses AI functions or static JSONB paths.\n  Defined per-workspace via settings API.\n\nFrozen: builtins are process-wide singletons exposed via the\n``BUILTIN_METRICS`` list. A mutable list field (e.g.\n``applies_to_product_types``) could otherwise be mutated by one caller\nand leak into every subsequent call in the same process."},"NameString":{"type":"string","maxLength":256,"minLength":1},"DescriptionString":{"type":"string","maxLength":2000},"MetricSettingsResponse":{"properties":{"definitions":{"items":{"$ref":"#/components/schemas/MetricDefinition"},"type":"array","title":"Definitions"}},"type":"object","required":["definitions"],"title":"MetricSettingsResponse"}}},"paths":{"/v1/{workspace_id}/settings/metrics":{"put":{"tags":["Settings"],"summary":"Update metric definitions","description":"Update the workspace metric definitions.\n\nPartial updates supported — only provided fields are changed.\nThe definitions list is replaced entirely when provided.\n\nPermissions: admin, owner.","operationId":"update-metric-settings","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricSettingsRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricSettingsResponse"}}}},"404":{"description":"Workspace not found"},"422":{"description":"Validation error"},"429":{"description":"Rate limited"}},"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Workspace Id"}}]}}}}
```

## Get outreach settings

> Get the workspace outreach settings.\
> \
> Returns empty rules and templates when not configured.\
> \
> Permissions: authenticated (any role).

```json
{"openapi":"3.1.0","info":{"title":"Platform API","version":"1.0.0"},"servers":[{"url":"https://api.platform.amigo.ai","description":"Production"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","description":"API key issued via `POST /v1/{workspace_id}/api-keys`. Pass the returned `api_key` value as a Bearer token."}},"schemas":{"OutreachSettingsResponse":{"properties":{"rules":{"items":{"$ref":"#/components/schemas/OutreachRule"},"type":"array","title":"Rules"},"data_templates":{"items":{"$ref":"#/components/schemas/DataTemplate-Output"},"type":"array","title":"Data Templates"}},"type":"object","required":["rules","data_templates"],"title":"OutreachSettingsResponse"},"OutreachRule":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"name":{"$ref":"#/components/schemas/NameString"},"trigger":{"type":"string","enum":["appointment_window","post_visit","gap_detected","form_intake","manual"],"title":"Trigger","default":"appointment_window"},"trigger_config":{"additionalProperties":true,"type":"object","title":"Trigger Config","description":"Trigger-specific config (hours_before, hours_after, etc.)"},"channel":{"$ref":"#/components/schemas/ChannelType","default":"email"},"consent_required":{"type":"boolean","title":"Consent Required","default":true},"quiet_hours":{"$ref":"#/components/schemas/QuietHours"},"review_required":{"type":"boolean","title":"Review Required","default":false},"message_template":{"type":"string","maxLength":1600,"title":"Message Template","default":"Hi {first_name}, please complete your form: {surface_url}"},"data_template_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Data Template Id"},"form_template_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Form Template Id"},"active":{"type":"boolean","title":"Active","default":true}},"type":"object","required":["name"],"title":"OutreachRule","description":"A single outreach rule — defines WHEN, WHAT, and HOW to reach a patient."},"NameString":{"type":"string","maxLength":256,"minLength":1},"ChannelType":{"type":"string","enum":["email","web","sms"],"title":"ChannelType","description":"Delivery channels for surfaces."},"QuietHours":{"properties":{"enabled":{"type":"boolean","title":"Enabled","default":false},"start_hour":{"type":"integer","maximum":23,"minimum":0,"title":"Start Hour","default":21},"end_hour":{"type":"integer","maximum":23,"minimum":0,"title":"End Hour","default":8},"timezone":{"type":"string","maxLength":64,"title":"Timezone","default":"America/New_York"}},"type":"object","title":"QuietHours","description":"Quiet hours — no outbound outreach during this window."},"DataTemplate-Output":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"name":{"$ref":"#/components/schemas/NameString"},"fields":{"items":{"$ref":"#/components/schemas/DataTemplateField"},"type":"array","maxItems":50,"minItems":1,"title":"Fields"}},"type":"object","required":["name","fields"],"title":"DataTemplate","description":"Named field template — reusable across multiple outreach rules."},"DataTemplateField":{"properties":{"key":{"type":"string","maxLength":128,"minLength":1,"title":"Key"},"label":{"$ref":"#/components/schemas/NameString"},"field_type":{"$ref":"#/components/schemas/FieldType","default":"text"},"required":{"type":"boolean","title":"Required","default":true},"sensitive":{"type":"boolean","title":"Sensitive","default":false},"path":{"type":"string","maxLength":256,"minLength":1,"title":"Path","description":"Dot-notation path into entity state (e.g. demographics.date_of_birth)"}},"type":"object","required":["key","label","path"],"title":"DataTemplateField","description":"A field in a data template — maps to entity state path for gap detection."},"FieldType":{"type":"string","enum":["text","textarea","date","phone","email","number","select","multiselect","checkbox","photo","signature","file","heading","info"],"title":"FieldType","description":"Input field types for surface data collection."}}},"paths":{"/v1/{workspace_id}/settings/outreach":{"get":{"tags":["Settings"],"summary":"Get outreach settings","description":"Get the workspace outreach settings.\n\nReturns empty rules and templates when not configured.\n\nPermissions: authenticated (any role).","operationId":"get-outreach-settings","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OutreachSettingsResponse"}}}},"429":{"description":"Rate limited"}},"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Workspace Id"}}]}}}}
```

## Update outreach settings

> Update the workspace outreach settings.\
> \
> Partial updates supported — only provided fields are changed.\
> Rules and data\_templates lists are replaced entirely when provided.\
> \
> Validates that data\_template\_id references in rules point to\
> templates that exist in the same payload or current settings.\
> \
> Permissions: admin, owner.

```json
{"openapi":"3.1.0","info":{"title":"Platform API","version":"1.0.0"},"servers":[{"url":"https://api.platform.amigo.ai","description":"Production"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","description":"API key issued via `POST /v1/{workspace_id}/api-keys`. Pass the returned `api_key` value as a Bearer token."}},"schemas":{"OutreachSettingsRequest":{"properties":{"rules":{"anyOf":[{"items":{"$ref":"#/components/schemas/OutreachRule"},"type":"array"},{"type":"null"}],"title":"Rules"},"data_templates":{"anyOf":[{"items":{"$ref":"#/components/schemas/DataTemplate-Input"},"type":"array"},{"type":"null"}],"title":"Data Templates"}},"type":"object","title":"OutreachSettingsRequest","description":"Partial update — only provided fields are changed.\n\nRules and data_templates lists are replaced entirely when provided."},"OutreachRule":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"name":{"$ref":"#/components/schemas/NameString"},"trigger":{"type":"string","enum":["appointment_window","post_visit","gap_detected","form_intake","manual"],"title":"Trigger","default":"appointment_window"},"trigger_config":{"additionalProperties":true,"type":"object","title":"Trigger Config","description":"Trigger-specific config (hours_before, hours_after, etc.)"},"channel":{"$ref":"#/components/schemas/ChannelType","default":"email"},"consent_required":{"type":"boolean","title":"Consent Required","default":true},"quiet_hours":{"$ref":"#/components/schemas/QuietHours"},"review_required":{"type":"boolean","title":"Review Required","default":false},"message_template":{"type":"string","maxLength":1600,"title":"Message Template","default":"Hi {first_name}, please complete your form: {surface_url}"},"data_template_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Data Template Id"},"form_template_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Form Template Id"},"active":{"type":"boolean","title":"Active","default":true}},"type":"object","required":["name"],"title":"OutreachRule","description":"A single outreach rule — defines WHEN, WHAT, and HOW to reach a patient."},"NameString":{"type":"string","maxLength":256,"minLength":1},"ChannelType":{"type":"string","enum":["email","web","sms"],"title":"ChannelType","description":"Delivery channels for surfaces."},"QuietHours":{"properties":{"enabled":{"type":"boolean","title":"Enabled","default":false},"start_hour":{"type":"integer","maximum":23,"minimum":0,"title":"Start Hour","default":21},"end_hour":{"type":"integer","maximum":23,"minimum":0,"title":"End Hour","default":8},"timezone":{"type":"string","maxLength":64,"title":"Timezone","default":"America/New_York"}},"type":"object","title":"QuietHours","description":"Quiet hours — no outbound outreach during this window."},"DataTemplate-Input":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"name":{"$ref":"#/components/schemas/NameString"},"fields":{"items":{"$ref":"#/components/schemas/DataTemplateField"},"type":"array","maxItems":50,"minItems":1,"title":"Fields"}},"type":"object","required":["name","fields"],"title":"DataTemplate","description":"Named field template — reusable across multiple outreach rules."},"DataTemplateField":{"properties":{"key":{"type":"string","maxLength":128,"minLength":1,"title":"Key"},"label":{"$ref":"#/components/schemas/NameString"},"field_type":{"$ref":"#/components/schemas/FieldType","default":"text"},"required":{"type":"boolean","title":"Required","default":true},"sensitive":{"type":"boolean","title":"Sensitive","default":false},"path":{"type":"string","maxLength":256,"minLength":1,"title":"Path","description":"Dot-notation path into entity state (e.g. demographics.date_of_birth)"}},"type":"object","required":["key","label","path"],"title":"DataTemplateField","description":"A field in a data template — maps to entity state path for gap detection."},"FieldType":{"type":"string","enum":["text","textarea","date","phone","email","number","select","multiselect","checkbox","photo","signature","file","heading","info"],"title":"FieldType","description":"Input field types for surface data collection."},"OutreachSettingsResponse":{"properties":{"rules":{"items":{"$ref":"#/components/schemas/OutreachRule"},"type":"array","title":"Rules"},"data_templates":{"items":{"$ref":"#/components/schemas/DataTemplate-Output"},"type":"array","title":"Data Templates"}},"type":"object","required":["rules","data_templates"],"title":"OutreachSettingsResponse"},"DataTemplate-Output":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"name":{"$ref":"#/components/schemas/NameString"},"fields":{"items":{"$ref":"#/components/schemas/DataTemplateField"},"type":"array","maxItems":50,"minItems":1,"title":"Fields"}},"type":"object","required":["name","fields"],"title":"DataTemplate","description":"Named field template — reusable across multiple outreach rules."}}},"paths":{"/v1/{workspace_id}/settings/outreach":{"put":{"tags":["Settings"],"summary":"Update outreach settings","description":"Update the workspace outreach settings.\n\nPartial updates supported — only provided fields are changed.\nRules and data_templates lists are replaced entirely when provided.\n\nValidates that data_template_id references in rules point to\ntemplates that exist in the same payload or current settings.\n\nPermissions: admin, owner.","operationId":"update-outreach-settings","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OutreachSettingsRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OutreachSettingsResponse"}}}},"404":{"description":"Workspace not found"},"422":{"description":"Validation error"},"429":{"description":"Rate limited"}},"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Workspace Id"}}]}}}}
```

## Get workspace branding

> Get the workspace default branding for surfaces.\
> \
> Returns empty branding when not configured.\
> \
> Permissions: authenticated (any role).

```json
{"openapi":"3.1.0","info":{"title":"Platform API","version":"1.0.0"},"servers":[{"url":"https://api.platform.amigo.ai","description":"Production"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","description":"API key issued via `POST /v1/{workspace_id}/api-keys`. Pass the returned `api_key` value as a Bearer token."}},"schemas":{"BrandingSettingsResponse":{"properties":{"branding":{"$ref":"#/components/schemas/BrandingConfig"}},"type":"object","required":["branding"],"title":"BrandingSettingsResponse"},"BrandingConfig":{"properties":{"logo_url":{"anyOf":[{"type":"string","maxLength":2048},{"type":"null"}],"title":"Logo Url"},"primary_color":{"anyOf":[{"type":"string","maxLength":32},{"type":"null"}],"title":"Primary Color"},"background_color":{"anyOf":[{"type":"string","maxLength":32},{"type":"null"}],"title":"Background Color"},"font_family":{"anyOf":[{"type":"string","maxLength":256},{"type":"null"}],"title":"Font Family"}},"type":"object","title":"BrandingConfig","description":"Visual branding for patient-facing surfaces."}}},"paths":{"/v1/{workspace_id}/settings/branding":{"get":{"tags":["Settings"],"summary":"Get workspace branding","description":"Get the workspace default branding for surfaces.\n\nReturns empty branding when not configured.\n\nPermissions: authenticated (any role).","operationId":"get-branding-settings","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BrandingSettingsResponse"}}}},"429":{"description":"Rate limited"}},"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Workspace Id"}}]}}}}
```

## Update workspace branding

> Update the workspace default branding for surfaces.\
> \
> Surface-level branding takes precedence over workspace-level branding.\
> \
> Permissions: admin, owner.

```json
{"openapi":"3.1.0","info":{"title":"Platform API","version":"1.0.0"},"servers":[{"url":"https://api.platform.amigo.ai","description":"Production"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","description":"API key issued via `POST /v1/{workspace_id}/api-keys`. Pass the returned `api_key` value as a Bearer token."}},"schemas":{"BrandingSettingsRequest":{"properties":{"branding":{"$ref":"#/components/schemas/BrandingConfig"}},"type":"object","required":["branding"],"title":"BrandingSettingsRequest","description":"Update workspace branding. All fields are optional — only provided\nfields are changed."},"BrandingConfig":{"properties":{"logo_url":{"anyOf":[{"type":"string","maxLength":2048},{"type":"null"}],"title":"Logo Url"},"primary_color":{"anyOf":[{"type":"string","maxLength":32},{"type":"null"}],"title":"Primary Color"},"background_color":{"anyOf":[{"type":"string","maxLength":32},{"type":"null"}],"title":"Background Color"},"font_family":{"anyOf":[{"type":"string","maxLength":256},{"type":"null"}],"title":"Font Family"}},"type":"object","title":"BrandingConfig","description":"Visual branding for patient-facing surfaces."},"BrandingSettingsResponse":{"properties":{"branding":{"$ref":"#/components/schemas/BrandingConfig"}},"type":"object","required":["branding"],"title":"BrandingSettingsResponse"}}},"paths":{"/v1/{workspace_id}/settings/branding":{"put":{"tags":["Settings"],"summary":"Update workspace branding","description":"Update the workspace default branding for surfaces.\n\nSurface-level branding takes precedence over workspace-level branding.\n\nPermissions: admin, owner.","operationId":"update-branding-settings","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BrandingSettingsRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BrandingSettingsResponse"}}}},"404":{"description":"Workspace not found"},"422":{"description":"Validation error"},"429":{"description":"Rate limited"}},"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Workspace Id"}}]}}}}
```

## Get environment overrides

> Get per-environment config overrides.\
> \
> Returns empty environments when not configured.\
> \
> Permissions: authenticated (any role).

```json
{"openapi":"3.1.0","info":{"title":"Platform API","version":"1.0.0"},"servers":[{"url":"https://api.platform.amigo.ai","description":"Production"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","description":"API key issued via `POST /v1/{workspace_id}/api-keys`. Pass the returned `api_key` value as a Bearer token."}},"schemas":{"EnvironmentSettingsResponse":{"properties":{"environments":{"additionalProperties":{"$ref":"#/components/schemas/EnvironmentOverrides"},"type":"object","title":"Environments"}},"type":"object","title":"EnvironmentSettingsResponse"},"EnvironmentOverrides":{"properties":{"data_source_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Data Source Id"},"tool_overrides":{"additionalProperties":true,"type":"object","title":"Tool Overrides"},"data_source_overrides":{"additionalProperties":true,"type":"object","title":"Data Source Overrides"}},"type":"object","title":"EnvironmentOverrides","description":"Per-environment config overrides merged at runtime."}}},"paths":{"/v1/{workspace_id}/settings/environments":{"get":{"tags":["Settings"],"summary":"Get environment overrides","description":"Get per-environment config overrides.\n\nReturns empty environments when not configured.\n\nPermissions: authenticated (any role).","operationId":"get-environment-settings","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnvironmentSettingsResponse"}}}},"429":{"description":"Rate limited"}},"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Workspace Id"}}]}}}}
```

## Update environment overrides

> Update per-environment config overrides.\
> \
> Permissions: admin, owner.

```json
{"openapi":"3.1.0","info":{"title":"Platform API","version":"1.0.0"},"servers":[{"url":"https://api.platform.amigo.ai","description":"Production"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","description":"API key issued via `POST /v1/{workspace_id}/api-keys`. Pass the returned `api_key` value as a Bearer token."}},"schemas":{"EnvironmentSettingsRequest":{"properties":{"environments":{"additionalProperties":{"$ref":"#/components/schemas/EnvironmentOverrides"},"type":"object","title":"Environments"}},"type":"object","required":["environments"],"title":"EnvironmentSettingsRequest"},"EnvironmentOverrides":{"properties":{"data_source_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Data Source Id"},"tool_overrides":{"additionalProperties":true,"type":"object","title":"Tool Overrides"},"data_source_overrides":{"additionalProperties":true,"type":"object","title":"Data Source Overrides"}},"type":"object","title":"EnvironmentOverrides","description":"Per-environment config overrides merged at runtime."},"EnvironmentSettingsResponse":{"properties":{"environments":{"additionalProperties":{"$ref":"#/components/schemas/EnvironmentOverrides"},"type":"object","title":"Environments"}},"type":"object","title":"EnvironmentSettingsResponse"}}},"paths":{"/v1/{workspace_id}/settings/environments":{"put":{"tags":["Settings"],"summary":"Update environment overrides","description":"Update per-environment config overrides.\n\nPermissions: admin, owner.","operationId":"update-environment-settings","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnvironmentSettingsRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnvironmentSettingsResponse"}}}},"404":{"description":"Workspace not found"},"422":{"description":"Validation error"},"429":{"description":"Rate limited"}},"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Workspace Id"}}]}}}}
```

## Get voice settings

> Get the voice experience settings for a workspace.\
> \
> Returns voice identity, domain vocabulary, and post-call intelligence\
> configuration. These settings shape how the AI agent sounds and what\
> domain-specific terms it recognizes accurately.\
> \
> \#### Permissions\
> \* Requires authenticated API key (any role).

```json
{"openapi":"3.1.0","info":{"title":"Platform API","version":"1.0.0"},"servers":[{"url":"https://api.platform.amigo.ai","description":"Production"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","description":"API key issued via `POST /v1/{workspace_id}/api-keys`. Pass the returned `api_key` value as a Bearer token."}},"schemas":{"VoiceSettingsResponse":{"properties":{"voice_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Voice Id"},"tone":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tone"},"speed":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Speed"},"volume":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Volume"},"language":{"type":"string","title":"Language"},"keyterms":{"items":{"type":"string"},"type":"array","title":"Keyterms"},"pronunciation_dict_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pronunciation Dict Id"},"sensitive_topics":{"items":{"type":"string"},"type":"array","title":"Sensitive Topics"},"post_call_analysis_enabled":{"type":"boolean","title":"Post Call Analysis Enabled"},"transcript_correction_enabled":{"type":"boolean","title":"Transcript Correction Enabled"},"stt_provider":{"anyOf":[{"type":"string","enum":["deepgram","openai","cartesia"]},{"type":"null"}],"title":"Stt Provider"},"tts_provider":{"anyOf":[{"type":"string","enum":["cartesia","elevenlabs","groq"]},{"type":"null"}],"title":"Tts Provider"},"tts_config":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Tts Config"},"language_providers":{"anyOf":[{"additionalProperties":{"$ref":"#/components/schemas/LanguageProviderEntry"},"type":"object"},{"type":"null"}],"title":"Language Providers"}},"type":"object","required":["voice_id","tone","speed","volume","language","keyterms","pronunciation_dict_id","sensitive_topics","post_call_analysis_enabled","transcript_correction_enabled","stt_provider","tts_provider","tts_config"],"title":"VoiceSettingsResponse","description":"Voice experience state — what the PM configured."},"LanguageProviderEntry":{"properties":{"provider":{"type":"string","enum":["cartesia","elevenlabs","groq"],"title":"Provider"},"config":{"additionalProperties":true,"type":"object","maxProperties":20,"title":"Config"}},"type":"object","required":["provider"],"title":"LanguageProviderEntry","description":"Per-language TTS provider configuration."}}},"paths":{"/v1/{workspace_id}/settings/voice":{"get":{"tags":["Settings"],"summary":"Get voice settings","description":"Get the voice experience settings for a workspace.\n\nReturns voice identity, domain vocabulary, and post-call intelligence\nconfiguration. These settings shape how the AI agent sounds and what\ndomain-specific terms it recognizes accurately.\n\n#### Permissions\n* Requires authenticated API key (any role).","operationId":"get-voice-settings","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VoiceSettingsResponse"}}}},"429":{"description":"Rate limited"}},"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Workspace Id"}}]}}}}
```

## Update voice settings

> Update the voice experience settings for a workspace.\
> \
> Only provided fields are updated; omitted fields retain their current\
> values. Set a field to \`\`null\`\` to reset it to default.\
> \
> \*\*Voice Identity & Style\*\*\
> \- \*\*voice\_id\*\*: Voice identity UUID — determines the agent's voice persona\
> \- \*\*tone\*\*: Emotional baseline (\`\`calm\`\`, \`\`sympathetic\`\`,\
> &#x20; \`\`enthusiastic\`\`, \`\`content\`\`, \`\`curious\`\`, \`\`cheerful\`\`,\
> &#x20; \`\`serious\`\`, \`\`friendly\`\`). The system also adapts tone dynamically\
> &#x20; based on real-time caller emotion analysis; this setting provides\
> &#x20; the baseline when no strong emotional signal is detected.\
> \- \*\*speed\*\*: Speech rate multiplier (0.5-2.0)\
> \- \*\*volume\*\*: Volume multiplier (0.0-1.0)\
> \- \*\*language\*\*: BCP-47 language tag (default \`\`en\`\`)\
> \
> \*\*Speech Recognition Boost\*\*\
> \- \*\*keyterms\*\*: Exact words the speech recognition engine should\
> &#x20; prioritize. Use for specific names, drug names, and org jargon.\
> &#x20; Example: \`\`\["Dr. Ramirez", "metformin", "HIPAA"]\`\`\
> \
> \*\*Post-Call Intelligence\*\*\
> \- \*\*post\_call\_analysis\_enabled\*\*: Run automated quality scoring after\
> &#x20; each call ends (default \`\`true\`\`)\
> \- \*\*transcript\_correction\_enabled\*\*: Re-verify transcripts with a\
> &#x20; high-accuracy batch model after call ends (default \`\`true\`\`)\
> \
> \#### Permissions\
> \* Requires admin or owner role.

```json
{"openapi":"3.1.0","info":{"title":"Platform API","version":"1.0.0"},"servers":[{"url":"https://api.platform.amigo.ai","description":"Production"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","description":"API key issued via `POST /v1/{workspace_id}/api-keys`. Pass the returned `api_key` value as a Bearer token."}},"schemas":{"VoiceSettingsRequest":{"properties":{"voice_id":{"anyOf":[{"type":"string","maxLength":128},{"type":"null"}],"title":"Voice Id"},"tone":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Tone"},"speed":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Speed"},"volume":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Volume"},"language":{"anyOf":[{"type":"string","maxLength":32},{"type":"null"}],"title":"Language"},"keyterms":{"anyOf":[{"items":{"type":"string","maxLength":128,"minLength":1},"type":"array","maxItems":200},{"type":"null"}],"title":"Keyterms"},"pronunciation_dict_id":{"anyOf":[{"type":"string","maxLength":128},{"type":"null"}],"title":"Pronunciation Dict Id"},"sensitive_topics":{"anyOf":[{"items":{"type":"string","maxLength":128,"minLength":1},"type":"array","maxItems":50},{"type":"null"}],"title":"Sensitive Topics"},"post_call_analysis_enabled":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Post Call Analysis Enabled"},"transcript_correction_enabled":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Transcript Correction Enabled"},"stt_provider":{"anyOf":[{"type":"string","enum":["deepgram","openai","cartesia"]},{"type":"null"}],"title":"Stt Provider"},"tts_provider":{"anyOf":[{"type":"string","enum":["cartesia","elevenlabs","groq"]},{"type":"null"}],"title":"Tts Provider"},"tts_config":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Tts Config"},"language_providers":{"anyOf":[{"additionalProperties":{"$ref":"#/components/schemas/LanguageProviderEntry"},"type":"object"},{"type":"null"}],"title":"Language Providers"}},"type":"object","title":"VoiceSettingsRequest","description":"Voice experience control plane — PM-facing, high-level controls.\n\nControls the caller experience without exposing engineering internals.\nEmotion detection, filler speech, model selection, and buffer tuning\nare always-on internals managed by engineering."},"LanguageProviderEntry":{"properties":{"provider":{"type":"string","enum":["cartesia","elevenlabs","groq"],"title":"Provider"},"config":{"additionalProperties":true,"type":"object","maxProperties":20,"title":"Config"}},"type":"object","required":["provider"],"title":"LanguageProviderEntry","description":"Per-language TTS provider configuration."},"VoiceSettingsResponse":{"properties":{"voice_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Voice Id"},"tone":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tone"},"speed":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Speed"},"volume":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Volume"},"language":{"type":"string","title":"Language"},"keyterms":{"items":{"type":"string"},"type":"array","title":"Keyterms"},"pronunciation_dict_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pronunciation Dict Id"},"sensitive_topics":{"items":{"type":"string"},"type":"array","title":"Sensitive Topics"},"post_call_analysis_enabled":{"type":"boolean","title":"Post Call Analysis Enabled"},"transcript_correction_enabled":{"type":"boolean","title":"Transcript Correction Enabled"},"stt_provider":{"anyOf":[{"type":"string","enum":["deepgram","openai","cartesia"]},{"type":"null"}],"title":"Stt Provider"},"tts_provider":{"anyOf":[{"type":"string","enum":["cartesia","elevenlabs","groq"]},{"type":"null"}],"title":"Tts Provider"},"tts_config":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Tts Config"},"language_providers":{"anyOf":[{"additionalProperties":{"$ref":"#/components/schemas/LanguageProviderEntry"},"type":"object"},{"type":"null"}],"title":"Language Providers"}},"type":"object","required":["voice_id","tone","speed","volume","language","keyterms","pronunciation_dict_id","sensitive_topics","post_call_analysis_enabled","transcript_correction_enabled","stt_provider","tts_provider","tts_config"],"title":"VoiceSettingsResponse","description":"Voice experience state — what the PM configured."}}},"paths":{"/v1/{workspace_id}/settings/voice":{"put":{"tags":["Settings"],"summary":"Update voice settings","description":"Update the voice experience settings for a workspace.\n\nOnly provided fields are updated; omitted fields retain their current\nvalues. Set a field to ``null`` to reset it to default.\n\n**Voice Identity & Style**\n- **voice_id**: Voice identity UUID — determines the agent's voice persona\n- **tone**: Emotional baseline (``calm``, ``sympathetic``,\n  ``enthusiastic``, ``content``, ``curious``, ``cheerful``,\n  ``serious``, ``friendly``). The system also adapts tone dynamically\n  based on real-time caller emotion analysis; this setting provides\n  the baseline when no strong emotional signal is detected.\n- **speed**: Speech rate multiplier (0.5-2.0)\n- **volume**: Volume multiplier (0.0-1.0)\n- **language**: BCP-47 language tag (default ``en``)\n\n**Speech Recognition Boost**\n- **keyterms**: Exact words the speech recognition engine should\n  prioritize. Use for specific names, drug names, and org jargon.\n  Example: ``[\"Dr. Ramirez\", \"metformin\", \"HIPAA\"]``\n\n**Post-Call Intelligence**\n- **post_call_analysis_enabled**: Run automated quality scoring after\n  each call ends (default ``true``)\n- **transcript_correction_enabled**: Re-verify transcripts with a\n  high-accuracy batch model after call ends (default ``true``)\n\n#### Permissions\n* Requires admin or owner role.","operationId":"update-voice-settings","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VoiceSettingsRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VoiceSettingsResponse"}}}},"404":{"description":"Workspace not found"},"422":{"description":"Validation error"},"429":{"description":"Rate limited"}},"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Workspace Id"}}]}}}}
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.amigo.ai/api-reference/readme/platform/settings.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
