# 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"}}}}}}
```

## 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.

```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.","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"}}}}}}
```

## 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":"sms"},"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":["sms","whatsapp","imessage","email","voice","web"],"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"}}}}}}
```

## 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.

```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":"sms"},"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":["sms","whatsapp","imessage","email","voice","web"],"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":"sms"},"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.","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"}}}}}}
```

## 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.

```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.","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"}}}}}}
```

## 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.

```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.","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"}}}}}}
```

## Get memory dimension settings

> Get the workspace memory dimension settings.\
> \
> 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":{"MemorySettingsResponse":{"properties":{"dimensions":{"items":{"$ref":"#/components/schemas/MemoryDimension"},"type":"array","title":"Dimensions"},"backfill_requested":{"type":"boolean","title":"Backfill Requested"}},"type":"object","required":["dimensions","backfill_requested"],"title":"MemorySettingsResponse"},"MemoryDimension":{"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 column key (e.g. 'clinical', 'cosmetic_preference')"},"name":{"$ref":"#/components/schemas/NameString"},"description":{"anyOf":[{"$ref":"#/components/schemas/DescriptionString"},{"type":"null"}]},"event_types":{"items":{"type":"string"},"type":"array","maxItems":100,"minItems":1,"title":"Event Types","description":"Event types to scan (e.g. 'patient.created', 'condition.created', 'surface.submitted')"},"extract_paths":{"items":{"type":"string"},"type":"array","maxItems":50,"title":"Extract Paths","description":"JSONB paths for static extraction (e.g. '$.active_conditions'). Ignored when extraction_mode='llm'."},"extraction_mode":{"type":"string","enum":["static","llm"],"title":"Extraction Mode","description":"'static' uses extract_paths (fast, free). 'llm' uses ai_extract with description as prompt (semantic, incremental).","default":"static"},"weight":{"type":"number","maximum":10,"minimum":0,"title":"Weight","description":"Relative importance for scoring (higher = more important)","default":1},"active":{"type":"boolean","title":"Active","default":true},"builtin":{"type":"boolean","title":"Builtin","description":"True for platform-provided dimensions (read-only key)","default":false}},"type":"object","required":["key","name","event_types"],"title":"MemoryDimension","description":"A single memory dimension — defines what facts to extract from events.\n\nTwo extraction modes:\n- static: uses extract_paths (JSONPath) for fast, free extraction\n- llm: uses ai_extract with the dimension description as prompt\n  for semantic extraction. Only runs on new events (incremental MV refresh)."},"NameString":{"type":"string","maxLength":256,"minLength":1},"DescriptionString":{"type":"string","maxLength":2000}}},"paths":{"/v1/{workspace_id}/settings/memory":{"get":{"tags":["Settings"],"summary":"Get memory dimension settings","description":"Get the workspace memory dimension settings.\n\nReturns built-in defaults when not configured.\n\nPermissions: authenticated (any role).","operationId":"get-memory-settings","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemorySettingsResponse"}}}},"429":{"description":"Rate limited"}}}}}}
```

## Update memory dimension settings

> Update the workspace memory dimension settings.\
> \
> Partial updates supported — only provided fields are changed.\
> The dimensions 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":{"MemorySettingsRequest":{"properties":{"dimensions":{"anyOf":[{"items":{"$ref":"#/components/schemas/MemoryDimension"},"type":"array"},{"type":"null"}],"title":"Dimensions"},"backfill_requested":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Backfill Requested"}},"type":"object","title":"MemorySettingsRequest","description":"Partial update — only provided fields are changed.\n\nThe dimensions list is replaced entirely when provided.\nBuilt-in dimensions can be deactivated (active=false) or have their\nweight changed, but their key cannot be reused for custom dimensions."},"MemoryDimension":{"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 column key (e.g. 'clinical', 'cosmetic_preference')"},"name":{"$ref":"#/components/schemas/NameString"},"description":{"anyOf":[{"$ref":"#/components/schemas/DescriptionString"},{"type":"null"}]},"event_types":{"items":{"type":"string"},"type":"array","maxItems":100,"minItems":1,"title":"Event Types","description":"Event types to scan (e.g. 'patient.created', 'condition.created', 'surface.submitted')"},"extract_paths":{"items":{"type":"string"},"type":"array","maxItems":50,"title":"Extract Paths","description":"JSONB paths for static extraction (e.g. '$.active_conditions'). Ignored when extraction_mode='llm'."},"extraction_mode":{"type":"string","enum":["static","llm"],"title":"Extraction Mode","description":"'static' uses extract_paths (fast, free). 'llm' uses ai_extract with description as prompt (semantic, incremental).","default":"static"},"weight":{"type":"number","maximum":10,"minimum":0,"title":"Weight","description":"Relative importance for scoring (higher = more important)","default":1},"active":{"type":"boolean","title":"Active","default":true},"builtin":{"type":"boolean","title":"Builtin","description":"True for platform-provided dimensions (read-only key)","default":false}},"type":"object","required":["key","name","event_types"],"title":"MemoryDimension","description":"A single memory dimension — defines what facts to extract from events.\n\nTwo extraction modes:\n- static: uses extract_paths (JSONPath) for fast, free extraction\n- llm: uses ai_extract with the dimension description as prompt\n  for semantic extraction. Only runs on new events (incremental MV refresh)."},"NameString":{"type":"string","maxLength":256,"minLength":1},"DescriptionString":{"type":"string","maxLength":2000},"MemorySettingsResponse":{"properties":{"dimensions":{"items":{"$ref":"#/components/schemas/MemoryDimension"},"type":"array","title":"Dimensions"},"backfill_requested":{"type":"boolean","title":"Backfill Requested"}},"type":"object","required":["dimensions","backfill_requested"],"title":"MemorySettingsResponse"}}},"paths":{"/v1/{workspace_id}/settings/memory":{"put":{"tags":["Settings"],"summary":"Update memory dimension settings","description":"Update the workspace memory dimension settings.\n\nPartial updates supported — only provided fields are changed.\nThe dimensions list is replaced entirely when provided.\n\nPermissions: admin, owner.","operationId":"update-memory-settings","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemorySettingsRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemorySettingsResponse"}}}},"404":{"description":"Workspace not found"},"422":{"description":"Validation error"},"429":{"description":"Rate limited"}}}}}}
```

## 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"],"title":"Source","description":"'call_intelligence' reads from world.call_intelligence table. 'world_events' reads from world.events. 'surface_events' reads from world.events WHERE domain='surface'."},"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_sentiment","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_sentiment' — AI sentiment analysis (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":"JSONB path for static extraction (e.g. '$.quality_score', '$.emotion_summary.dominant_emotion'). 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":2000},{"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}'"},"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, ai_sentiment). '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"},"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."},"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"}}}}}}
```

## 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"],"title":"Source","description":"'call_intelligence' reads from world.call_intelligence table. 'world_events' reads from world.events. 'surface_events' reads from world.events WHERE domain='surface'."},"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_sentiment","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_sentiment' — AI sentiment analysis (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":"JSONB path for static extraction (e.g. '$.quality_score', '$.emotion_summary.dominant_emotion'). 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":2000},{"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}'"},"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, ai_sentiment). '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"},"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."},"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"}}}}}}
```

## 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":"sms"},"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":["sms","whatsapp","imessage","email","voice","web"],"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":"TCPA-compliant quiet hours — no outbound SMS 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"}}}}}}
```

## 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":"sms"},"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":["sms","whatsapp","imessage","email","voice","web"],"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":"TCPA-compliant quiet hours — no outbound SMS 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"}}}}}}
```

## Get dynamic behavior settings

> Get the workspace dynamic behavior settings.\
> \
> Returns defaults (disabled, empty) 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":{"BehaviorSettingsResponse":{"properties":{"enabled":{"type":"boolean","title":"Enabled"},"behaviors":{"items":{"$ref":"#/components/schemas/BehaviorDef"},"type":"array","title":"Behaviors"}},"type":"object","required":["enabled","behaviors"],"title":"BehaviorSettingsResponse"},"BehaviorDef":{"properties":{"name":{"$ref":"#/components/schemas/NameString"},"description":{"$ref":"#/components/schemas/DescriptionString","default":""},"trigger":{"$ref":"#/components/schemas/BehaviorTrigger"},"action":{"$ref":"#/components/schemas/BehaviorAction"},"cooldown_turns":{"type":"integer","maximum":100,"minimum":0,"title":"Cooldown Turns","default":3},"priority":{"type":"integer","maximum":10,"minimum":-10,"title":"Priority","default":0},"enabled":{"type":"boolean","title":"Enabled","default":true}},"type":"object","required":["name"],"title":"BehaviorDef","description":"A named dynamic behavior definition."},"NameString":{"type":"string","maxLength":256,"minLength":1},"DescriptionString":{"type":"string","maxLength":2000},"BehaviorTrigger":{"properties":{"keywords":{"items":{"type":"string"},"type":"array","maxItems":50,"title":"Keywords"},"intent_categories":{"items":{"type":"string"},"type":"array","maxItems":20,"title":"Intent Categories"},"emotion_tiers":{"items":{"type":"integer"},"type":"array","maxItems":4,"title":"Emotion Tiers","description":"Empathy tiers (0-3) that activate this behavior"},"states":{"items":{"type":"string"},"type":"array","maxItems":50,"title":"States","description":"Context graph state names that activate this behavior"}},"type":"object","title":"BehaviorTrigger","description":"Conditions that activate this behavior."},"BehaviorAction":{"properties":{"turn_policy_overrides":{"additionalProperties":true,"type":"object","title":"Turn Policy Overrides"},"instruction":{"type":"string","maxLength":2000,"title":"Instruction","description":"Instruction injected into the engage prompt when active","default":""},"add_tools":{"items":{"type":"string"},"type":"array","maxItems":20,"title":"Add Tools","description":"Tool names to make available when active"},"remove_tools":{"items":{"type":"string"},"type":"array","maxItems":20,"title":"Remove Tools","description":"Tool names to hide when active"},"filler_override":{"anyOf":[{"type":"string","enum":["empathy","receipt","working","silent"]},{"type":"null"}],"title":"Filler Override","description":"Override filler type when active"}},"type":"object","title":"BehaviorAction","description":"What happens when the behavior activates."}}},"paths":{"/v1/{workspace_id}/settings/behaviors":{"get":{"tags":["Settings"],"summary":"Get dynamic behavior settings","description":"Get the workspace dynamic behavior settings.\n\nReturns defaults (disabled, empty) when not configured.\n\nPermissions: authenticated (any role).","operationId":"get-behavior-settings","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BehaviorSettingsResponse"}}}},"429":{"description":"Rate limited"}}}}}}
```

## Update dynamic behavior settings

> Update the workspace dynamic behavior settings.\
> \
> Partial updates supported — only provided fields are changed.\
> Behaviors 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":{"BehaviorSettingsRequest":{"properties":{"enabled":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Enabled"},"behaviors":{"anyOf":[{"items":{"$ref":"#/components/schemas/BehaviorDef"},"type":"array","maxItems":100},{"type":"null"}],"title":"Behaviors"}},"type":"object","title":"BehaviorSettingsRequest","description":"Partial update — only provided fields are changed."},"BehaviorDef":{"properties":{"name":{"$ref":"#/components/schemas/NameString"},"description":{"$ref":"#/components/schemas/DescriptionString","default":""},"trigger":{"$ref":"#/components/schemas/BehaviorTrigger"},"action":{"$ref":"#/components/schemas/BehaviorAction"},"cooldown_turns":{"type":"integer","maximum":100,"minimum":0,"title":"Cooldown Turns","default":3},"priority":{"type":"integer","maximum":10,"minimum":-10,"title":"Priority","default":0},"enabled":{"type":"boolean","title":"Enabled","default":true}},"type":"object","required":["name"],"title":"BehaviorDef","description":"A named dynamic behavior definition."},"NameString":{"type":"string","maxLength":256,"minLength":1},"DescriptionString":{"type":"string","maxLength":2000},"BehaviorTrigger":{"properties":{"keywords":{"items":{"type":"string"},"type":"array","maxItems":50,"title":"Keywords"},"intent_categories":{"items":{"type":"string"},"type":"array","maxItems":20,"title":"Intent Categories"},"emotion_tiers":{"items":{"type":"integer"},"type":"array","maxItems":4,"title":"Emotion Tiers","description":"Empathy tiers (0-3) that activate this behavior"},"states":{"items":{"type":"string"},"type":"array","maxItems":50,"title":"States","description":"Context graph state names that activate this behavior"}},"type":"object","title":"BehaviorTrigger","description":"Conditions that activate this behavior."},"BehaviorAction":{"properties":{"turn_policy_overrides":{"additionalProperties":true,"type":"object","title":"Turn Policy Overrides"},"instruction":{"type":"string","maxLength":2000,"title":"Instruction","description":"Instruction injected into the engage prompt when active","default":""},"add_tools":{"items":{"type":"string"},"type":"array","maxItems":20,"title":"Add Tools","description":"Tool names to make available when active"},"remove_tools":{"items":{"type":"string"},"type":"array","maxItems":20,"title":"Remove Tools","description":"Tool names to hide when active"},"filler_override":{"anyOf":[{"type":"string","enum":["empathy","receipt","working","silent"]},{"type":"null"}],"title":"Filler Override","description":"Override filler type when active"}},"type":"object","title":"BehaviorAction","description":"What happens when the behavior activates."},"BehaviorSettingsResponse":{"properties":{"enabled":{"type":"boolean","title":"Enabled"},"behaviors":{"items":{"$ref":"#/components/schemas/BehaviorDef"},"type":"array","title":"Behaviors"}},"type":"object","required":["enabled","behaviors"],"title":"BehaviorSettingsResponse"}}},"paths":{"/v1/{workspace_id}/settings/behaviors":{"put":{"tags":["Settings"],"summary":"Update dynamic behavior settings","description":"Update the workspace dynamic behavior settings.\n\nPartial updates supported — only provided fields are changed.\nBehaviors list is replaced entirely when provided.\n\nPermissions: admin, owner.","operationId":"update-behavior-settings","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BehaviorSettingsRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BehaviorSettingsResponse"}}}},"404":{"description":"Workspace not found"},"422":{"description":"Validation error"},"429":{"description":"Rate limited"}}}}}}
```

## 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"}}}}}}
```

## 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"}}}}}}
```

## 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"}}}}}}
```

## 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"}}}}}}
```

## Get workflow specs

> Get workflow specs for this workspace.\
> \
> 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":{"WorkflowSettingsResponse":{"properties":{"workflows":{"items":{"$ref":"#/components/schemas/WorkflowSpec-Output"},"type":"array","title":"Workflows"}},"type":"object","title":"WorkflowSettingsResponse"},"WorkflowSpec-Output":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"},"description":{"type":"string","title":"Description","default":""},"trigger":{"$ref":"#/components/schemas/WorkflowTrigger"},"input_query":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Input Query"},"steps":{"items":{"$ref":"#/components/schemas/WorkflowStep-Output"},"type":"array","title":"Steps"},"timeout":{"type":"string","format":"duration","title":"Timeout","default":"P7D"},"max_concurrent":{"type":"integer","title":"Max Concurrent","default":10},"enabled":{"type":"boolean","title":"Enabled","default":true}},"type":"object","required":["name","trigger","steps"],"title":"WorkflowSpec","description":"A workflow definition stored in workspace settings.\n\nWorkflows are identified by name (unique within a workspace)."},"WorkflowTrigger":{"properties":{"type":{"type":"string","enum":["cron","event","manual"],"title":"Type"},"cron_expression":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cron Expression"},"event_filter":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Event Filter"}},"type":"object","required":["type"],"title":"WorkflowTrigger","description":"When and how a workflow starts."},"WorkflowStep-Output":{"properties":{"name":{"type":"string","title":"Name"},"type":{"type":"string","enum":["tool_call","integration_call","wait","branch","for_each","surface"],"title":"Type"},"tool_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tool Name"},"tool_params":{"additionalProperties":true,"type":"object","title":"Tool Params"},"integration":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Integration"},"endpoint":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Endpoint"},"request_body":{"additionalProperties":true,"type":"object","title":"Request Body"},"wait_duration":{"anyOf":[{"type":"string","format":"duration"},{"type":"null"}],"title":"Wait Duration"},"wait_for_event":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Wait For Event"},"condition":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Condition"},"on_true":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"On True"},"on_false":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"On False"},"items_from":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Items From"},"body_steps":{"anyOf":[{"items":{"$ref":"#/components/schemas/WorkflowStep-Output"},"type":"array"},{"type":"null"}],"title":"Body Steps"},"surface_spec":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Surface Spec"},"retry_count":{"type":"integer","title":"Retry Count","default":3},"retry_backoff_seconds":{"type":"number","title":"Retry Backoff Seconds","default":2}},"type":"object","required":["name","type"],"title":"WorkflowStep","description":"A single step in a workflow spec.\n\nSteps are declarative — no LLM decides which step to run next.\nThe engine executes them sequentially unless branch/for_each alters flow."}}},"paths":{"/v1/{workspace_id}/settings/workflows":{"get":{"tags":["Settings"],"summary":"Get workflow specs","description":"Get workflow specs for this workspace.\n\nPermissions: authenticated (any role).","operationId":"get-workflow-settings","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowSettingsResponse"}}}},"429":{"description":"Rate limited"}}}}}}
```

## Update workflow specs

> Update workflow specs.\
> \
> 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":{"WorkflowSettingsRequest":{"properties":{"workflows":{"items":{"$ref":"#/components/schemas/WorkflowSpec-Input"},"type":"array","maxItems":100,"title":"Workflows"}},"type":"object","required":["workflows"],"title":"WorkflowSettingsRequest"},"WorkflowSpec-Input":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"},"description":{"type":"string","title":"Description","default":""},"trigger":{"$ref":"#/components/schemas/WorkflowTrigger"},"input_query":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Input Query"},"steps":{"items":{"$ref":"#/components/schemas/WorkflowStep-Input"},"type":"array","title":"Steps"},"timeout":{"type":"string","format":"duration","title":"Timeout","default":"P7D"},"max_concurrent":{"type":"integer","title":"Max Concurrent","default":10},"enabled":{"type":"boolean","title":"Enabled","default":true}},"type":"object","required":["name","trigger","steps"],"title":"WorkflowSpec","description":"A workflow definition stored in workspace settings.\n\nWorkflows are identified by name (unique within a workspace)."},"WorkflowTrigger":{"properties":{"type":{"type":"string","enum":["cron","event","manual"],"title":"Type"},"cron_expression":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cron Expression"},"event_filter":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Event Filter"}},"type":"object","required":["type"],"title":"WorkflowTrigger","description":"When and how a workflow starts."},"WorkflowStep-Input":{"properties":{"name":{"type":"string","title":"Name"},"type":{"type":"string","enum":["tool_call","integration_call","wait","branch","for_each","surface"],"title":"Type"},"tool_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tool Name"},"tool_params":{"additionalProperties":true,"type":"object","title":"Tool Params"},"integration":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Integration"},"endpoint":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Endpoint"},"request_body":{"additionalProperties":true,"type":"object","title":"Request Body"},"wait_duration":{"anyOf":[{"type":"string","format":"duration"},{"type":"null"}],"title":"Wait Duration"},"wait_for_event":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Wait For Event"},"condition":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Condition"},"on_true":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"On True"},"on_false":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"On False"},"items_from":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Items From"},"body_steps":{"anyOf":[{"items":{"$ref":"#/components/schemas/WorkflowStep-Input"},"type":"array"},{"type":"null"}],"title":"Body Steps"},"surface_spec":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Surface Spec"},"retry_count":{"type":"integer","title":"Retry Count","default":3},"retry_backoff_seconds":{"type":"number","title":"Retry Backoff Seconds","default":2}},"type":"object","required":["name","type"],"title":"WorkflowStep","description":"A single step in a workflow spec.\n\nSteps are declarative — no LLM decides which step to run next.\nThe engine executes them sequentially unless branch/for_each alters flow."},"WorkflowSettingsResponse":{"properties":{"workflows":{"items":{"$ref":"#/components/schemas/WorkflowSpec-Output"},"type":"array","title":"Workflows"}},"type":"object","title":"WorkflowSettingsResponse"},"WorkflowSpec-Output":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"},"description":{"type":"string","title":"Description","default":""},"trigger":{"$ref":"#/components/schemas/WorkflowTrigger"},"input_query":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Input Query"},"steps":{"items":{"$ref":"#/components/schemas/WorkflowStep-Output"},"type":"array","title":"Steps"},"timeout":{"type":"string","format":"duration","title":"Timeout","default":"P7D"},"max_concurrent":{"type":"integer","title":"Max Concurrent","default":10},"enabled":{"type":"boolean","title":"Enabled","default":true}},"type":"object","required":["name","trigger","steps"],"title":"WorkflowSpec","description":"A workflow definition stored in workspace settings.\n\nWorkflows are identified by name (unique within a workspace)."},"WorkflowStep-Output":{"properties":{"name":{"type":"string","title":"Name"},"type":{"type":"string","enum":["tool_call","integration_call","wait","branch","for_each","surface"],"title":"Type"},"tool_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tool Name"},"tool_params":{"additionalProperties":true,"type":"object","title":"Tool Params"},"integration":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Integration"},"endpoint":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Endpoint"},"request_body":{"additionalProperties":true,"type":"object","title":"Request Body"},"wait_duration":{"anyOf":[{"type":"string","format":"duration"},{"type":"null"}],"title":"Wait Duration"},"wait_for_event":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Wait For Event"},"condition":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Condition"},"on_true":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"On True"},"on_false":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"On False"},"items_from":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Items From"},"body_steps":{"anyOf":[{"items":{"$ref":"#/components/schemas/WorkflowStep-Output"},"type":"array"},{"type":"null"}],"title":"Body Steps"},"surface_spec":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Surface Spec"},"retry_count":{"type":"integer","title":"Retry Count","default":3},"retry_backoff_seconds":{"type":"number","title":"Retry Backoff Seconds","default":2}},"type":"object","required":["name","type"],"title":"WorkflowStep","description":"A single step in a workflow spec.\n\nSteps are declarative — no LLM decides which step to run next.\nThe engine executes them sequentially unless branch/for_each alters flow."}}},"paths":{"/v1/{workspace_id}/settings/workflows":{"put":{"tags":["Settings"],"summary":"Update workflow specs","description":"Update workflow specs.\n\nPermissions: admin, owner.","operationId":"update-workflow-settings","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowSettingsRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowSettingsResponse"}}}},"404":{"description":"Workspace not found"},"422":{"description":"Validation error"},"429":{"description":"Rate limited"}}}}}}
```

## Get Superscribe access settings

> Get workspace Superscribe access settings.\
> \
> Returns the list of authorized clinicians and whether scribe is enabled.\
> \
> 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":{"ScribeSettingsResponse":{"properties":{"enabled":{"type":"boolean","title":"Enabled"},"authorized_clinicians":{"items":{"$ref":"#/components/schemas/ScribeClinician"},"type":"array","title":"Authorized Clinicians"},"soap_style":{"type":"string","enum":["concise","detailed","structured"],"title":"Soap Style","default":"concise"},"safety":{"$ref":"#/components/schemas/ScribeSafetyConfig"},"cds":{"$ref":"#/components/schemas/ScribeCdsConfig"},"post_encounter":{"$ref":"#/components/schemas/ScribePostEncounterConfig"},"voice_auth_enabled":{"type":"boolean","title":"Voice Auth Enabled","default":false}},"type":"object","required":["enabled","authorized_clinicians"],"title":"ScribeSettingsResponse"},"ScribeClinician":{"properties":{"email":{"type":"string","format":"email","title":"Email"},"name":{"anyOf":[{"type":"string","maxLength":256},{"type":"null"}],"title":"Name"},"role":{"type":"string","maxLength":64,"title":"Role","default":"clinician"}},"type":"object","required":["email"],"title":"ScribeClinician","description":"A clinician authorized to use Superscribe."},"ScribeSafetyConfig":{"properties":{"drug_interaction_checking":{"type":"boolean","title":"Drug Interaction Checking","default":true},"allergy_cross_reference":{"type":"boolean","title":"Allergy Cross Reference","default":true},"crisis_detection":{"type":"boolean","title":"Crisis Detection","default":true},"vital_range_alerting":{"type":"boolean","title":"Vital Range Alerting","default":true}},"type":"object","title":"ScribeSafetyConfig","description":"V0 sentinel and safety configuration."},"ScribeCdsConfig":{"properties":{"care_gap_surfacing":{"type":"boolean","title":"Care Gap Surfacing","default":true},"icd10_auto_suggest":{"type":"boolean","title":"Icd10 Auto Suggest","default":true},"guideline_matching":{"type":"boolean","title":"Guideline Matching","default":false},"documentation_completeness":{"type":"boolean","title":"Documentation Completeness","default":true}},"type":"object","title":"ScribeCdsConfig","description":"Clinical decision support configuration (V2/V3 workers)."},"ScribePostEncounterConfig":{"properties":{"auto_polish_note":{"type":"boolean","title":"Auto Polish Note","default":true},"order_preparation":{"type":"boolean","title":"Order Preparation","default":false},"education_materials":{"type":"boolean","title":"Education Materials","default":false},"follow_up_surface":{"type":"boolean","title":"Follow Up Surface","default":false}},"type":"object","title":"ScribePostEncounterConfig","description":"Post-encounter automation configuration."}}},"paths":{"/v1/{workspace_id}/settings/scribe":{"get":{"tags":["Settings"],"summary":"Get Superscribe access settings","description":"Get workspace Superscribe access settings.\n\nReturns the list of authorized clinicians and whether scribe is enabled.\n\nPermissions: authenticated (any role).","operationId":"get-scribe-settings","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScribeSettingsResponse"}}}},"429":{"description":"Rate limited"}}}}}}
```

## Update Superscribe access settings

> Update workspace Superscribe access settings.\
> \
> Manages which clinicians can authenticate to Superscribe via Google OAuth.\
> \
> 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":{"ScribeSettingsRequest":{"properties":{"enabled":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Enabled"},"authorized_clinicians":{"anyOf":[{"items":{"$ref":"#/components/schemas/ScribeClinician"},"type":"array","maxItems":500},{"type":"null"}],"title":"Authorized Clinicians"},"soap_style":{"anyOf":[{"type":"string","enum":["concise","detailed","structured"]},{"type":"null"}],"title":"Soap Style"},"safety":{"anyOf":[{"$ref":"#/components/schemas/ScribeSafetyConfig"},{"type":"null"}]},"cds":{"anyOf":[{"$ref":"#/components/schemas/ScribeCdsConfig"},{"type":"null"}]},"post_encounter":{"anyOf":[{"$ref":"#/components/schemas/ScribePostEncounterConfig"},{"type":"null"}]},"voice_auth_enabled":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Voice Auth Enabled"}},"type":"object","title":"ScribeSettingsRequest","description":"Partial update — only provided fields are changed."},"ScribeClinician":{"properties":{"email":{"type":"string","format":"email","title":"Email"},"name":{"anyOf":[{"type":"string","maxLength":256},{"type":"null"}],"title":"Name"},"role":{"type":"string","maxLength":64,"title":"Role","default":"clinician"}},"type":"object","required":["email"],"title":"ScribeClinician","description":"A clinician authorized to use Superscribe."},"ScribeSafetyConfig":{"properties":{"drug_interaction_checking":{"type":"boolean","title":"Drug Interaction Checking","default":true},"allergy_cross_reference":{"type":"boolean","title":"Allergy Cross Reference","default":true},"crisis_detection":{"type":"boolean","title":"Crisis Detection","default":true},"vital_range_alerting":{"type":"boolean","title":"Vital Range Alerting","default":true}},"type":"object","title":"ScribeSafetyConfig","description":"V0 sentinel and safety configuration."},"ScribeCdsConfig":{"properties":{"care_gap_surfacing":{"type":"boolean","title":"Care Gap Surfacing","default":true},"icd10_auto_suggest":{"type":"boolean","title":"Icd10 Auto Suggest","default":true},"guideline_matching":{"type":"boolean","title":"Guideline Matching","default":false},"documentation_completeness":{"type":"boolean","title":"Documentation Completeness","default":true}},"type":"object","title":"ScribeCdsConfig","description":"Clinical decision support configuration (V2/V3 workers)."},"ScribePostEncounterConfig":{"properties":{"auto_polish_note":{"type":"boolean","title":"Auto Polish Note","default":true},"order_preparation":{"type":"boolean","title":"Order Preparation","default":false},"education_materials":{"type":"boolean","title":"Education Materials","default":false},"follow_up_surface":{"type":"boolean","title":"Follow Up Surface","default":false}},"type":"object","title":"ScribePostEncounterConfig","description":"Post-encounter automation configuration."},"ScribeSettingsResponse":{"properties":{"enabled":{"type":"boolean","title":"Enabled"},"authorized_clinicians":{"items":{"$ref":"#/components/schemas/ScribeClinician"},"type":"array","title":"Authorized Clinicians"},"soap_style":{"type":"string","enum":["concise","detailed","structured"],"title":"Soap Style","default":"concise"},"safety":{"$ref":"#/components/schemas/ScribeSafetyConfig"},"cds":{"$ref":"#/components/schemas/ScribeCdsConfig"},"post_encounter":{"$ref":"#/components/schemas/ScribePostEncounterConfig"},"voice_auth_enabled":{"type":"boolean","title":"Voice Auth Enabled","default":false}},"type":"object","required":["enabled","authorized_clinicians"],"title":"ScribeSettingsResponse"}}},"paths":{"/v1/{workspace_id}/settings/scribe":{"put":{"tags":["Settings"],"summary":"Update Superscribe access settings","description":"Update workspace Superscribe access settings.\n\nManages which clinicians can authenticate to Superscribe via Google OAuth.\n\nPermissions: admin, owner.","operationId":"update-scribe-settings","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScribeSettingsRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScribeSettingsResponse"}}}},"404":{"description":"Workspace not found"},"422":{"description":"Validation error"},"429":{"description":"Rate limited"}}}}}}
```

## 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"},"correction_categories":{"items":{"type":"string"},"type":"array","title":"Correction Categories"},"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"}},"type":"object","required":["voice_id","tone","speed","volume","language","keyterms","correction_categories","pronunciation_dict_id","sensitive_topics","post_call_analysis_enabled","transcript_correction_enabled"],"title":"VoiceSettingsResponse","description":"Voice experience state — what the PM configured."}}},"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"}}}}}}
```

## 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", "InFocus", "HIPAA"]\`\`\
> \
> \*\*Audio Correction Hints\*\*\
> \- \*\*correction\_categories\*\*: Broad categories of things callers\
> &#x20; commonly say that speech-to-text gets wrong. Not exact words —\
> &#x20; just what \*kinds\* of things to watch for. Example:\
> &#x20; \`\`\["medication names", "insurance carriers", "doctor last names"]\`\`\
> \
> \*\*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"},{"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":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Language"},"keyterms":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Keyterms"},"correction_categories":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Correction Categories"},"pronunciation_dict_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pronunciation Dict Id"},"sensitive_topics":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"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"}},"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."},"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"},"correction_categories":{"items":{"type":"string"},"type":"array","title":"Correction Categories"},"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"}},"type":"object","required":["voice_id","tone","speed","volume","language","keyterms","correction_categories","pronunciation_dict_id","sensitive_topics","post_call_analysis_enabled","transcript_correction_enabled"],"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\", \"InFocus\", \"HIPAA\"]``\n\n**Audio Correction Hints**\n- **correction_categories**: Broad categories of things callers\n  commonly say that speech-to-text gets wrong. Not exact words —\n  just what *kinds* of things to watch for. Example:\n  ``[\"medication names\", \"insurance carriers\", \"doctor last names\"]``\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"}}}}}}
```
