Docs

advise

LLM-backed advisor — the agent-callable action plus admin config and metering.

Amfelt REST API · v1.13.0 · https://api.amfelt.com


GET /v1/advise/usage  

List LLM-usage events.

Returns LLM-usage rows for the caller’s organization, newest first, with the page’s aggregate cost.

Parameters  

NameInRequiredTypeDescription
X-Tenant-SlugheaderYesstringSlug of the organization to scope the request to; required for user-authenticated requests.
Slug of the organization to scope the request to; required for user-authenticated requests.
envqueryNostringDTAP environment to scope the request to; defaults server-side to the api’s configured environment.
DTAP environment to scope the request to; defaults server-side to the api’s configured environment.
cursorqueryNostringOpaque cursor for the next page; pass back the ’next_cursor’ from a prior response.
Opaque cursor for the next page; pass back the ’next_cursor’ from a prior response.
limitqueryNointegerMaximum number of items to return per page.
Maximum number of items to return per page.

Responses  

200 A page of LLM-usage events with the page's total cost.

application/json

PropertyTypeRequiredDescription
dataLlmUsage []YesThe page of usage rows.
The page of usage rows.
next_cursor[string null]NoOpaque cursor for the next page, or null when this is the final page. Examples: eyJpZCI6OTk5fQ.
Opaque cursor for the next page, or null when this is the final page. Examples: eyJpZCI6OTk5fQ.
total_cost_usdnumberYesSum of cost_usd across the returned rows; per-page aggregate.
Sum of cost_usd across the returned rows; per-page aggregate.
400 The request was malformed or failed validation.

application/json

PropertyTypeRequiredDescription
codestringYesStable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
Stable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
fieldstringNoOptional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
Optional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
messagestringYesHuman-readable description of the error. Examples: limit must be between 1 and 100.
Human-readable description of the error. Examples: limit must be between 1 and 100.
401 The request lacks valid credentials.

application/json

PropertyTypeRequiredDescription
codestringYesStable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
Stable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
fieldstringNoOptional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
Optional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
messagestringYesHuman-readable description of the error. Examples: limit must be between 1 and 100.
Human-readable description of the error. Examples: limit must be between 1 and 100.
403 The caller is authenticated but not permitted to perform the request.

application/json

PropertyTypeRequiredDescription
codestringYesStable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
Stable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
fieldstringNoOptional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
Optional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
messagestringYesHuman-readable description of the error. Examples: limit must be between 1 and 100.
Human-readable description of the error. Examples: limit must be between 1 and 100.

Security  

bearer_jwt


GET /v1/advise/providers  

List the providers and models an own key may use.

Returns the providers an own key may be registered for, with the models each accepts and whether it needs a base_url on this deployment, and the provider and model of the caller’s organization’s calls on the Amfelt platform key. The provider list is the server-side allowlist that setAdvisorOwnKey and updateAdviseConfig validate against, so a client offers only values they accept. It names no key and reads no vault. Every role reads it.

Parameters  

NameInRequiredTypeDescription
X-Tenant-SlugheaderYesstringSlug of the organization to scope the request to; required for user-authenticated requests.
Slug of the organization to scope the request to; required for user-authenticated requests.

Responses  

200 The own-key providers and the platform key's provider and model.

application/json

PropertyTypeRequiredDescription
dataAdvisorProvider []YesThe providers an own key may be registered for.
The providers an own key may be registered for.
platform_modelstringYesThe model of the caller’s organization’s calls on the platform key: LlmConfig.model while provider_source is platform. Named whether or not this deployment has a platform key configured; without one, a call on the platform key answers no_answer with reason no_provider. Examples: claude-sonnet-5-5.
The model of the caller’s organization’s calls on the platform key: LlmConfig.model while provider_source is platform. Named whether or not this deployment has a platform key configured; without one, a call on the platform key answers no_answer with reason no_provider. Examples: claude-sonnet-5-5.
platform_providerstringYesThe provider of the Amfelt platform key’s calls. Examples: anthropic.
The provider of the Amfelt platform key’s calls. Examples: anthropic.
401 The request lacks valid credentials.

application/json

PropertyTypeRequiredDescription
codestringYesStable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
Stable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
fieldstringNoOptional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
Optional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
messagestringYesHuman-readable description of the error. Examples: limit must be between 1 and 100.
Human-readable description of the error. Examples: limit must be between 1 and 100.
403 The caller is authenticated but not permitted to perform the request.

application/json

PropertyTypeRequiredDescription
codestringYesStable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
Stable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
fieldstringNoOptional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
Optional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
messagestringYesHuman-readable description of the error. Examples: limit must be between 1 and 100.
Human-readable description of the error. Examples: limit must be between 1 and 100.

Security  

bearer_jwt


POST /v1/advise/notice/dismiss  

Dismiss the one-time advisor invitation for the caller.

Records that the caller dismissed the advisor invitation in the caller’s organization. Dismissing chooses nothing: the advisor stays off. Idempotent: a second dismissal keeps the first dismissed_at.

Parameters  

NameInRequiredTypeDescription
X-Tenant-SlugheaderYesstringSlug of the organization to scope the request to; required for user-authenticated requests.
Slug of the organization to scope the request to; required for user-authenticated requests.

Responses  

200 The invitation state after the dismissal; show is false.

application/json

PropertyTypeRequiredDescription
dismissed_at[string null]YesWhen the caller dismissed the invitation. Always present on the wire; null while not dismissed.
When the caller dismissed the invitation. Always present on the wire; null while not dismissed.
showbooleanYesWhether the app shows the invitation to the caller now: true only for an owner or admin of an organization with no recorded choice at all (never switched on or off), who has not dismissed it.
Whether the app shows the invitation to the caller now: true only for an owner or admin of an organization with no recorded choice at all (never switched on or off), who has not dismissed it.
401 The request lacks valid credentials.

application/json

PropertyTypeRequiredDescription
codestringYesStable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
Stable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
fieldstringNoOptional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
Optional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
messagestringYesHuman-readable description of the error. Examples: limit must be between 1 and 100.
Human-readable description of the error. Examples: limit must be between 1 and 100.
403 The caller is authenticated but not permitted to perform the request.

application/json

PropertyTypeRequiredDescription
codestringYesStable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
Stable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
fieldstringNoOptional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
Optional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
messagestringYesHuman-readable description of the error. Examples: limit must be between 1 and 100.
Human-readable description of the error. Examples: limit must be between 1 and 100.

Security  

bearer_jwt


GET /v1/advise/notice  

Get whether to show the caller the one-time advisor invitation.

The one-time invitation to opt in, for owners and admins of an organization with no recorded choice at all: setAdvisorEnabled was never called for it, on or off (enabled_changed_at is null), as for one that existed before onboarding asked. An organization that declined, at onboarding or later, has a recorded off choice and is never invited. The invitation tells them the advisor is off, what switching it on sends and costs, and links to the advisor settings; it never switches the advisor on. The record is per account and organization, so a dismissal holds across devices. show is true only for an owner or admin of an organization with no recorded choice who has not dismissed it.

Parameters  

NameInRequiredTypeDescription
X-Tenant-SlugheaderYesstringSlug of the organization to scope the request to; required for user-authenticated requests.
Slug of the organization to scope the request to; required for user-authenticated requests.

Responses  

200 Whether to show the invitation to the caller.

application/json

PropertyTypeRequiredDescription
dismissed_at[string null]YesWhen the caller dismissed the invitation. Always present on the wire; null while not dismissed.
When the caller dismissed the invitation. Always present on the wire; null while not dismissed.
showbooleanYesWhether the app shows the invitation to the caller now: true only for an owner or admin of an organization with no recorded choice at all (never switched on or off), who has not dismissed it.
Whether the app shows the invitation to the caller now: true only for an owner or admin of an organization with no recorded choice at all (never switched on or off), who has not dismissed it.
401 The request lacks valid credentials.

application/json

PropertyTypeRequiredDescription
codestringYesStable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
Stable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
fieldstringNoOptional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
Optional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
messagestringYesHuman-readable description of the error. Examples: limit must be between 1 and 100.
Human-readable description of the error. Examples: limit must be between 1 and 100.
403 The caller is authenticated but not permitted to perform the request.

application/json

PropertyTypeRequiredDescription
codestringYesStable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
Stable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
fieldstringNoOptional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
Optional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
messagestringYesHuman-readable description of the error. Examples: limit must be between 1 and 100.
Human-readable description of the error. Examples: limit must be between 1 and 100.

Security  

bearer_jwt


PUT /v1/advise/enabled  

Switch the organization's advisor on or off.

Sets whether the advisor may be asked for the caller’s organization, in every environment and on either key. The advisor is off by default: this operation is the only way an organization becomes enabled, and it is the explicit opt-in that authorizes provider calls (api#1237). An owner or admin may switch it on or off (org.llm-config.update); operator and viewer cannot. The onboarding step and the Advisor tab both make it, and it records the caller as enabled_changed_by, the time, the disclosure_version shown with the choice, and where it was made (reason, read back as enabled_reason). Off is a choice too: continuing onboarding with the advisor box unchecked sends enabled false through this operation, so the organization has a recorded choice and is never invited (getAdvisorNotice). It changes no environment’s provider settings and no own key. With the advisor off, no advisor call leaves the organization: every advise answers no_answer with reason disabled.

Parameters  

NameInRequiredTypeDescription
X-Tenant-SlugheaderYesstringSlug of the organization to scope the request to; required for user-authenticated requests.
Slug of the organization to scope the request to; required for user-authenticated requests.

Request body (required)  

application/json

PropertyTypeRequiredDescription
disclosure_versionstringYesThe version of the disclosure the person saw with the choice: what the advisor sends to Claude (Anthropic) and the free allowance. The api records it with the choice and returns it on reads. Examples: advisor-disclosure-2026-10-17.
The version of the disclosure the person saw with the choice: what the advisor sends to Claude (Anthropic) and the free allowance. The api records it with the choice and returns it on reads. Examples: advisor-disclosure-2026-10-17.
enabledbooleanYesSwitches the advisor on (true) or off (false) for the whole organization.
Switches the advisor on (true) or off (false) for the whole organization.
reasonAdvisorEnabledReasonNo

Responses  

200 The organization's advisor switch after the save.

application/json

PropertyTypeRequiredDescription
disclosure_version[string null]YesThe version of the disclosure shown with the last choice; null when the organization never chose. Examples: advisor-disclosure-2026-10-17.
The version of the disclosure shown with the last choice; null when the organization never chose. Examples: advisor-disclosure-2026-10-17.
enabledbooleanYesWhether the advisor may be asked for this organization, on either key.
Whether the advisor may be asked for this organization, on either key.
enabled_changed_at[string null]YesWhen the organization’s advisor was last switched on or off; null when never.
When the organization’s advisor was last switched on or off; null when never.
enabled_changed_byYesThe account that last switched the organization’s advisor on or off; null when the organization never chose.
The account that last switched the organization’s advisor on or off; null when the organization never chose.
enabled_reasonYesWhere the last choice was made: onboarding or settings (AdvisorEnabledUpdate.reason); null when the organization never chose.
Where the last choice was made: onboarding or settings (AdvisorEnabledUpdate.reason); null when the organization never chose.
400 The request was malformed or failed validation.

application/json

PropertyTypeRequiredDescription
codestringYesStable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
Stable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
fieldstringNoOptional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
Optional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
messagestringYesHuman-readable description of the error. Examples: limit must be between 1 and 100.
Human-readable description of the error. Examples: limit must be between 1 and 100.
401 The request lacks valid credentials.

application/json

PropertyTypeRequiredDescription
codestringYesStable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
Stable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
fieldstringNoOptional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
Optional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
messagestringYesHuman-readable description of the error. Examples: limit must be between 1 and 100.
Human-readable description of the error. Examples: limit must be between 1 and 100.
403 The caller is authenticated but not permitted to perform the request.

application/json

PropertyTypeRequiredDescription
codestringYesStable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
Stable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
fieldstringNoOptional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
Optional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
messagestringYesHuman-readable description of the error. Examples: limit must be between 1 and 100.
Human-readable description of the error. Examples: limit must be between 1 and 100.

Security  

bearer_jwt


GET /v1/advise/config  

Get the current LLM advisor config.

Returns the advisor settings for the caller’s organization in the requested environment: whether the advisor is on, which key that environment’s calls run on (provider_source, derived from whether an own key is registered there, never saved), the provider and model, whether an own key is registered (never the key), and who last changed the settings and when. Every role reads them; only an owner or admin changes them (setAdvisorEnabled, updateAdviseConfig, setAdvisorOwnKey, removeAdvisorOwnKey). A read never creates or enables settings: an organization that never saved them reads enabled false and a null enabled_changed_at. enabled is one value for the organization; the provider settings are those of the requested environment.

Parameters  

NameInRequiredTypeDescription
X-Tenant-SlugheaderYesstringSlug of the organization to scope the request to; required for user-authenticated requests.
Slug of the organization to scope the request to; required for user-authenticated requests.
envqueryNostringDTAP environment to scope the request to; defaults server-side to the api’s configured environment.
DTAP environment to scope the request to; defaults server-side to the api’s configured environment.

Responses  

200 The current LLM config.

application/json

PropertyTypeRequiredDescription
base_urlstringNoThe own key’s OpenAI-compatible gateway base URL (ADR-091), as saved. Only meaningful for provider gateway; absent while provider_source is platform. A default gateway exists only where this deployment pins a gateway base URL: there an empty value uses the pinned one, and the pinned one wins over a saved value. A deployment that pins none refuses an empty base_url for provider gateway when an own key is registered (setAdvisorOwnKey). Examples: http://litellm:4000/v1.
The own key’s OpenAI-compatible gateway base URL (ADR-091), as saved. Only meaningful for provider gateway; absent while provider_source is platform. A default gateway exists only where this deployment pins a gateway base URL: there an empty value uses the pinned one, and the pinned one wins over a saved value. A deployment that pins none refuses an empty base_url for provider gateway when an own key is registered (setAdvisorOwnKey). Examples: http://litellm:4000/v1.
changed_at[string null]NoWhen this environment’s own key or provider settings last changed. Always present on the wire; null when never.
When this environment’s own key or provider settings last changed. Always present on the wire; null when never.
changed_byNoThe account that last changed this environment’s own key or its provider settings (setAdvisorOwnKey, removeAdvisorOwnKey, updateAdviseConfig). Always present on the wire; null when none was ever changed.
The account that last changed this environment’s own key or its provider settings (setAdvisorOwnKey, removeAdvisorOwnKey, updateAdviseConfig). Always present on the wire; null when none was ever changed.
disclosure_version[string null]NoThe version of the disclosure shown to the account that last switched the advisor on or off (AdvisorEnabledUpdate). Always present on the wire; null when the organization never chose. Examples: advisor-disclosure-2026-10-17.
The version of the disclosure shown to the account that last switched the advisor on or off (AdvisorEnabledUpdate). Always present on the wire; null when the organization never chose. Examples: advisor-disclosure-2026-10-17.
enabledbooleanYesWhether the advisor may be asked for this organization. One value for the whole organization, the same in every environment’s read; the provider settings below are per environment. Off by default: false for an organization that never chose, and only setAdvisorEnabled by an owner or admin turns it on. No missing row, registered key, allowance or provider default reads as true. When false, no advisor call leaves the organization on either key.
Whether the advisor may be asked for this organization. One value for the whole organization, the same in every environment’s read; the provider settings below are per environment. Off by default: false for an organization that never chose, and only setAdvisorEnabled by an owner or admin turns it on. No missing row, registered key, allowance or provider default reads as true. When false, no advisor call leaves the organization on either key.
enabled_changed_at[string null]NoWhen the organization’s advisor was last switched on or off. Always present on the wire; null when never.
When the organization’s advisor was last switched on or off. Always present on the wire; null when never.
enabled_changed_byNoThe account that last switched the organization’s advisor on or off. Always present on the wire; null when the organization never chose.
The account that last switched the organization’s advisor on or off. Always present on the wire; null when the organization never chose.
enabled_reasonNoWhere the advisor was last switched on or off: onboarding or settings (AdvisorEnabledUpdate.reason). Always present on the wire; null when the organization never chose.
Where the advisor was last switched on or off: onboarding or settings (AdvisorEnabledUpdate.reason). Always present on the wire; null when the organization never chose.
envstringYesDTAP environment this config applies to. Examples: production.
DTAP environment this config applies to. Examples: production.
modelstringYesThe LLM model this environment’s calls run on: the own key’s saved model while provider_source is own_key, the organization’s platform-key model while it is platform. Examples: claude-sonnet-5-5.
The LLM model this environment’s calls run on: the own key’s saved model while provider_source is own_key, the organization’s platform-key model while it is platform. Examples: claude-sonnet-5-5.
own_keyAdvisorOwnKeyStatusYes
providerstringYesThe LLM provider this environment’s calls run on: the own key’s while provider_source is own_key, the platform key’s while it is platform (e.g. anthropic, openai, gateway for an OpenAI-compatible gateway endpoint). Examples: anthropic.
The LLM provider this environment’s calls run on: the own key’s while provider_source is own_key, the platform key’s while it is platform (e.g. anthropic, openai, gateway for an OpenAI-compatible gateway endpoint). Examples: anthropic.
provider_sourceAdvisorProviderSourceYes
vault_refstringYesInformational vault path where the organization’s own LLM API key is (or would be) stored for this environment and provider. The Amfelt platform key is never stored in an organization vault. Examples: production/llm/anthropic.
Informational vault path where the organization’s own LLM API key is (or would be) stored for this environment and provider. The Amfelt platform key is never stored in an organization vault. Examples: production/llm/anthropic.
400 The request was malformed or failed validation.

application/json

PropertyTypeRequiredDescription
codestringYesStable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
Stable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
fieldstringNoOptional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
Optional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
messagestringYesHuman-readable description of the error. Examples: limit must be between 1 and 100.
Human-readable description of the error. Examples: limit must be between 1 and 100.
401 The request lacks valid credentials.

application/json

PropertyTypeRequiredDescription
codestringYesStable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
Stable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
fieldstringNoOptional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
Optional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
messagestringYesHuman-readable description of the error. Examples: limit must be between 1 and 100.
Human-readable description of the error. Examples: limit must be between 1 and 100.
403 The caller is authenticated but not permitted to perform the request.

application/json

PropertyTypeRequiredDescription
codestringYesStable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
Stable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
fieldstringNoOptional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
Optional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
messagestringYesHuman-readable description of the error. Examples: limit must be between 1 and 100.
Human-readable description of the error. Examples: limit must be between 1 and 100.

Security  

bearer_jwt


PUT /v1/advise/config  

Update the LLM advisor config.

Upserts the saved provider settings of one environment for the caller’s organization: provider, model and base_url, for the environment env names. Provider and model are validated against the server-side allowlist (listAdvisorProviders). The save records the caller as changed_by. It never switches the advisor on or off (setAdvisorEnabled does), and it never changes which key a call runs on, nor an own key’s settings.

While an own key is registered in the environment, that key’s provider, model and base_url change only through setAdvisorOwnKey: a body whose provider, model or base_url differs from them answers 409 (code conflict) and changes nothing, so this operation cannot move the environment’s calls off its own key by naming another provider. A body equal to them answers 200 with nothing changed. While no own key is registered, the environment’s calls run on the platform key with the platform key’s provider and the organization’s platform model (AdvisorProviderList.platform_provider and platform_model, LlmConfig.model) whatever this saves, and no call uses the saved settings. base_url is refused with 400 when no own key is registered, since only an own key’s calls use it.

Parameters  

NameInRequiredTypeDescription
X-Tenant-SlugheaderYesstringSlug of the organization to scope the request to; required for user-authenticated requests.
Slug of the organization to scope the request to; required for user-authenticated requests.

Request body (required)  

application/json

PropertyTypeRequiredDescription
base_urlstringNoOptional OpenAI-compatible gateway base URL (ADR-091) of the own key. Only meaningful for provider gateway. A default gateway exists only where this deployment pins a gateway base URL: there an empty or absent value uses the pinned one, and the pinned one wins over the value saved here. A deployment that pins none has no default gateway, so there an own key on provider gateway always has a base_url (setAdvisorOwnKey refuses an empty one). Refused with 400 when no own key is registered in this environment: only an own key’s calls use it. While one is registered it must equal that key’s base_url (409 otherwise). Examples: http://litellm:4000/v1.
Optional OpenAI-compatible gateway base URL (ADR-091) of the own key. Only meaningful for provider gateway. A default gateway exists only where this deployment pins a gateway base URL: there an empty or absent value uses the pinned one, and the pinned one wins over the value saved here. A deployment that pins none has no default gateway, so there an own key on provider gateway always has a base_url (setAdvisorOwnKey refuses an empty one). Refused with 400 when no own key is registered in this environment: only an own key’s calls use it. While one is registered it must equal that key’s base_url (409 otherwise). Examples: http://litellm:4000/v1.
envstringNoDTAP environment; defaults server-side to the api’s configured environment. Examples: production.
DTAP environment; defaults server-side to the api’s configured environment. Examples: production.
modelstringYesLLM model; validated against the server-side allowlist for the provider. Examples: claude-sonnet-4-6.
LLM model; validated against the server-side allowlist for the provider. Examples: claude-sonnet-4-6.
providerstringYesLLM provider; validated against the server-side allowlist (e.g. anthropic, openai, gateway for an OpenAI-compatible gateway endpoint). Examples: anthropic.
LLM provider; validated against the server-side allowlist (e.g. anthropic, openai, gateway for an OpenAI-compatible gateway endpoint). Examples: anthropic.

Responses  

200 The updated LLM config.

application/json

PropertyTypeRequiredDescription
base_urlstringNoThe own key’s OpenAI-compatible gateway base URL (ADR-091), as saved. Only meaningful for provider gateway; absent while provider_source is platform. A default gateway exists only where this deployment pins a gateway base URL: there an empty value uses the pinned one, and the pinned one wins over a saved value. A deployment that pins none refuses an empty base_url for provider gateway when an own key is registered (setAdvisorOwnKey). Examples: http://litellm:4000/v1.
The own key’s OpenAI-compatible gateway base URL (ADR-091), as saved. Only meaningful for provider gateway; absent while provider_source is platform. A default gateway exists only where this deployment pins a gateway base URL: there an empty value uses the pinned one, and the pinned one wins over a saved value. A deployment that pins none refuses an empty base_url for provider gateway when an own key is registered (setAdvisorOwnKey). Examples: http://litellm:4000/v1.
changed_at[string null]NoWhen this environment’s own key or provider settings last changed. Always present on the wire; null when never.
When this environment’s own key or provider settings last changed. Always present on the wire; null when never.
changed_byNoThe account that last changed this environment’s own key or its provider settings (setAdvisorOwnKey, removeAdvisorOwnKey, updateAdviseConfig). Always present on the wire; null when none was ever changed.
The account that last changed this environment’s own key or its provider settings (setAdvisorOwnKey, removeAdvisorOwnKey, updateAdviseConfig). Always present on the wire; null when none was ever changed.
disclosure_version[string null]NoThe version of the disclosure shown to the account that last switched the advisor on or off (AdvisorEnabledUpdate). Always present on the wire; null when the organization never chose. Examples: advisor-disclosure-2026-10-17.
The version of the disclosure shown to the account that last switched the advisor on or off (AdvisorEnabledUpdate). Always present on the wire; null when the organization never chose. Examples: advisor-disclosure-2026-10-17.
enabledbooleanYesWhether the advisor may be asked for this organization. One value for the whole organization, the same in every environment’s read; the provider settings below are per environment. Off by default: false for an organization that never chose, and only setAdvisorEnabled by an owner or admin turns it on. No missing row, registered key, allowance or provider default reads as true. When false, no advisor call leaves the organization on either key.
Whether the advisor may be asked for this organization. One value for the whole organization, the same in every environment’s read; the provider settings below are per environment. Off by default: false for an organization that never chose, and only setAdvisorEnabled by an owner or admin turns it on. No missing row, registered key, allowance or provider default reads as true. When false, no advisor call leaves the organization on either key.
enabled_changed_at[string null]NoWhen the organization’s advisor was last switched on or off. Always present on the wire; null when never.
When the organization’s advisor was last switched on or off. Always present on the wire; null when never.
enabled_changed_byNoThe account that last switched the organization’s advisor on or off. Always present on the wire; null when the organization never chose.
The account that last switched the organization’s advisor on or off. Always present on the wire; null when the organization never chose.
enabled_reasonNoWhere the advisor was last switched on or off: onboarding or settings (AdvisorEnabledUpdate.reason). Always present on the wire; null when the organization never chose.
Where the advisor was last switched on or off: onboarding or settings (AdvisorEnabledUpdate.reason). Always present on the wire; null when the organization never chose.
envstringYesDTAP environment this config applies to. Examples: production.
DTAP environment this config applies to. Examples: production.
modelstringYesThe LLM model this environment’s calls run on: the own key’s saved model while provider_source is own_key, the organization’s platform-key model while it is platform. Examples: claude-sonnet-5-5.
The LLM model this environment’s calls run on: the own key’s saved model while provider_source is own_key, the organization’s platform-key model while it is platform. Examples: claude-sonnet-5-5.
own_keyAdvisorOwnKeyStatusYes
providerstringYesThe LLM provider this environment’s calls run on: the own key’s while provider_source is own_key, the platform key’s while it is platform (e.g. anthropic, openai, gateway for an OpenAI-compatible gateway endpoint). Examples: anthropic.
The LLM provider this environment’s calls run on: the own key’s while provider_source is own_key, the platform key’s while it is platform (e.g. anthropic, openai, gateway for an OpenAI-compatible gateway endpoint). Examples: anthropic.
provider_sourceAdvisorProviderSourceYes
vault_refstringYesInformational vault path where the organization’s own LLM API key is (or would be) stored for this environment and provider. The Amfelt platform key is never stored in an organization vault. Examples: production/llm/anthropic.
Informational vault path where the organization’s own LLM API key is (or would be) stored for this environment and provider. The Amfelt platform key is never stored in an organization vault. Examples: production/llm/anthropic.
400 The request was malformed or failed validation.

application/json

PropertyTypeRequiredDescription
codestringYesStable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
Stable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
fieldstringNoOptional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
Optional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
messagestringYesHuman-readable description of the error. Examples: limit must be between 1 and 100.
Human-readable description of the error. Examples: limit must be between 1 and 100.
401 The request lacks valid credentials.

application/json

PropertyTypeRequiredDescription
codestringYesStable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
Stable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
fieldstringNoOptional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
Optional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
messagestringYesHuman-readable description of the error. Examples: limit must be between 1 and 100.
Human-readable description of the error. Examples: limit must be between 1 and 100.
403 The caller is authenticated but not permitted to perform the request.

application/json

PropertyTypeRequiredDescription
codestringYesStable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
Stable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
fieldstringNoOptional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
Optional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
messagestringYesHuman-readable description of the error. Examples: limit must be between 1 and 100.
Human-readable description of the error. Examples: limit must be between 1 and 100.
409 Code conflict: an own key is registered in the environment and the body's provider, model or base_url differs from that key's. Change them with setAdvisorOwnKey. Nothing is changed.

application/json

PropertyTypeRequiredDescription
codestringYesStable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
Stable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
fieldstringNoOptional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
Optional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
messagestringYesHuman-readable description of the error. Examples: limit must be between 1 and 100.
Human-readable description of the error. Examples: limit must be between 1 and 100.

Security  

bearer_jwt


GET /v1/advise/calls  

List the organization's recent advisor calls.

Returns the advisor call log of the caller’s organization only (the organization X-Tenant-Slug names, which the caller must be a member of), newest first: per call the object it was about, its environment, the result (auto_applied, awaiting_approval, no_answer, or null while no classification is stored with the call’s id), its tokens, and whether it was metered against the allowance. Every role reads it. The call log holds a row only for an advise that passed postAdvise step 2 and was answered with outcome answered (a cache hit included) or with a planned no-answer with reason no_provider, allowance_exhausted or own_key_failed. An advise of a disabled organization (reason disabled) and a control-plane failure (5xx) write no row, and neither does a request refused with 403.

Parameters  

NameInRequiredTypeDescription
X-Tenant-SlugheaderYesstringSlug of the organization to scope the request to; required for user-authenticated requests.
Slug of the organization to scope the request to; required for user-authenticated requests.
cursorqueryNostringOpaque cursor for the next page; pass back the ’next_cursor’ from a prior response.
Opaque cursor for the next page; pass back the ’next_cursor’ from a prior response.
limitqueryNointegerMaximum number of items to return per page.
Maximum number of items to return per page.

Responses  

200 A page of advisor calls, newest first.

application/json

PropertyTypeRequiredDescription
dataAdvisorCall []YesThe page of calls.
The page of calls.
next_cursor[string null]NoOpaque cursor for the next page, or null when this is the final page.
Opaque cursor for the next page, or null when this is the final page.
400 The request was malformed or failed validation.

application/json

PropertyTypeRequiredDescription
codestringYesStable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
Stable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
fieldstringNoOptional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
Optional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
messagestringYesHuman-readable description of the error. Examples: limit must be between 1 and 100.
Human-readable description of the error. Examples: limit must be between 1 and 100.
401 The request lacks valid credentials.

application/json

PropertyTypeRequiredDescription
codestringYesStable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
Stable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
fieldstringNoOptional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
Optional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
messagestringYesHuman-readable description of the error. Examples: limit must be between 1 and 100.
Human-readable description of the error. Examples: limit must be between 1 and 100.
403 The caller is authenticated but not permitted to perform the request.

application/json

PropertyTypeRequiredDescription
codestringYesStable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
Stable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
fieldstringNoOptional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
Optional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
messagestringYesHuman-readable description of the error. Examples: limit must be between 1 and 100.
Human-readable description of the error. Examples: limit must be between 1 and 100.

Security  

bearer_jwt


GET /v1/advise/allowance  

Get the organization's free advisor token allowance.

Returns the caller’s organization’s free token allowance on the Amfelt platform key: the allowance, the tokens used against it, what is left, and how many calls were metered. The allowance is one value for the organization, shared by every environment, so this read takes no environment. Only calls on the platform key count; calls on the organization’s own key are logged but never metered. When nothing is left, an advise call that reaches postAdvise step 5 on the platform key answers no_answer with reason allowance_exhausted, and its table stops after staging and waits for classification (awaiting_classification). The earlier steps still answer first: a disabled organization’s call answers no_answer with reason disabled and its table does not wait (step 1), and cached advice is still served, at no cost to the allowance (step 4). Registering an own key for the environment, or raising the allowance, lets a later call reach a provider. Every role reads it.

Parameters  

NameInRequiredTypeDescription
X-Tenant-SlugheaderYesstringSlug of the organization to scope the request to; required for user-authenticated requests.
Slug of the organization to scope the request to; required for user-authenticated requests.

Responses  

200 The organization's allowance.

application/json

PropertyTypeRequiredDescription
allowance_tokensintegerYesThe allowance. Set per organization by a sysadmin (setOrgAdvisorAllowance). Examples: 500000.
The allowance. Set per organization by a sysadmin (setOrgAdvisorAllowance). Examples: 500000.
metered_callsintegerYesThe number of calls metered against the allowance; with used_tokens it gives the average tokens per call, from which a client can estimate the tables the remainder covers. Examples: 40.
The number of calls metered against the allowance; with used_tokens it gives the average tokens per call, from which a client can estimate the tables the remainder covers. Examples: 40.
remaining_tokensintegerYesallowance_tokens minus used_tokens, and never below 0. Examples: 380000.
allowance_tokens minus used_tokens, and never below 0. Examples: 380000.
used_tokensintegerYesTokens metered against the allowance so far. Calls already in flight when the allowance runs out are still metered, so this may exceed allowance_tokens. Examples: 120000.
Tokens metered against the allowance so far. Calls already in flight when the allowance runs out are still metered, so this may exceed allowance_tokens. Examples: 120000.
401 The request lacks valid credentials.

application/json

PropertyTypeRequiredDescription
codestringYesStable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
Stable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
fieldstringNoOptional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
Optional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
messagestringYesHuman-readable description of the error. Examples: limit must be between 1 and 100.
Human-readable description of the error. Examples: limit must be between 1 and 100.
403 The caller is authenticated but not permitted to perform the request.

application/json

PropertyTypeRequiredDescription
codestringYesStable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
Stable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
fieldstringNoOptional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
Optional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
messagestringYesHuman-readable description of the error. Examples: limit must be between 1 and 100.
Human-readable description of the error. Examples: limit must be between 1 and 100.

Security  

bearer_jwt


POST /v1/advise  

Request advice.

Submits a contract and TOON profile to the configured LLM and returns the advisor’s response. Agent-callable, and only by an agent: the api authenticates the call with the calling agent’s JWT (agent-auth), never with a member’s token, so no member can call it, and every check below reads the calling agent. It carries no customer permission. It stores no classification and changes no configuration: the agent files an answer through ingestCatalogClassifications. It never sets classification or PII-label state: the stored state is carried over (ClassificationStatus).

The api decides each request in this order, and a step that answers ends the request:

  1. Enablement. The advisor must be enabled for the organization. It is off until an owner or admin switches it on (setAdvisorEnabled); an organization that never chose is off. The api checks this first, before it returns cached advice, resolves either key, selects a provider or calls any LLM. When it is off, nothing is sent, nothing cached is returned and no call-log row is written: no_answer with reason disabled. Disabled is a normal product path, not a wait: an agent built on this contract then loads the object’s history in its resolved history mode (the job’s, or the default) and does not leave it waiting for classification.
  2. Environment and assignment. The call resolves in the environment the request names (AdviseRequest.environment) or, when it names none, in the api’s configured environment. Named or not, that environment must be a project environment whose runs dispatch to the calling agent (setProjectEnvironmentAgent), and, when the request names project_id, an environment of that project. Otherwise the api answers 403 (code permission_denied): nothing is sent, nothing cached is returned and no call-log row is written.
  3. Settings. The environment’s settings decide which key the call runs on (LlmConfig.provider_source): its own key while one is registered there (at {env}/llm/{provider}, see setAdvisorOwnKey), the Amfelt platform key otherwise, each with its provider and model, and an own key on provider gateway with its base URL (LlmConfig.base_url). An own key on provider gateway with no usable base URL answers no_answer with reason own_key_failed.
  4. Cache. Cached advice is served only at this step, so only to an enabled organization and an assigned agent: a cached answer for the same organization, provider settings, contract and profile answers outcome answered with cache_hit true and 0 tokens. A cache hit asks no provider, is never metered and costs no allowance, so it is served even when the allowance is used up. It writes a call-log row like any answered call, so its answer can be filed with advisor_call_id.
  5. Key and provider. On the own key, the api reads the key from the environment’s vault (503 when it cannot) and asks its provider; the call is never metered. When the provider refuses or fails on that key (an invalid key, its quota, an outage or a timeout of its provider), the answer is no_answer with reason own_key_failed; the platform key is never used in its place. On the platform key, the api checks the allowance before any provider call: no_answer with reason allowance_exhausted when none is left, and with reason no_provider when this deployment has no platform key configured. Otherwise it asks the platform key’s provider, and the call is metered.

A no_answer is a 200: the api sent nothing to a provider, or its own key failed. It is a designed answer, not an outage, and the agent stores no classification. With reason disabled the object does not wait (step 1). With reason own_key_failed, allowance_exhausted or no_provider, as after an outage, the object stops after staging and waits for classification; an unsure answer waits too, for approval of its proposal. Only failures on the control plane’s side are 5xx: reading the own key from the organization vault (503), the platform key’s provider (502, and 504 on its timeout), and internal errors (500). A 5xx writes no call-log row; the call log holds a row only for a request that passed step 2 and was answered with outcome answered or with a no_answer other than disabled (listAdvisorCalls).

Request body (required)  

application/json

PropertyTypeRequiredDescription
contract_yamlstringYesODCS contract YAML; capped at 512 KB server-side.
ODCS contract YAML; capped at 512 KB server-side.
environmentstringNoThe DTAP environment of the run that asks. It selects the environment whose own key and provider settings resolve the call (postAdvise), and is recorded on the call’s row in the advisor call log. Optional for compatibility: absent, the api’s configured environment resolves the call, as it did before this field. Named or not, the environment the call resolves in must be a project environment whose runs dispatch to the calling agent (setProjectEnvironmentAgent). This is postAdvise step 2, after enablement: a disabled organization’s call answers 200 no_answer with reason disabled at step 1, before this check. An enabled organization’s call that fails it answers 403 (code permission_denied) and sends nothing. An agent built on this contract sends it. Examples: development.
The DTAP environment of the run that asks. It selects the environment whose own key and provider settings resolve the call (postAdvise), and is recorded on the call’s row in the advisor call log. Optional for compatibility: absent, the api’s configured environment resolves the call, as it did before this field. Named or not, the environment the call resolves in must be a project environment whose runs dispatch to the calling agent (setProjectEnvironmentAgent). This is postAdvise step 2, after enablement: a disabled organization’s call answers 200 no_answer with reason disabled at step 1, before this check. An enabled organization’s call that fails it answers 403 (code permission_denied) and sends nothing. An agent built on this contract sends it. Examples: development.
featurestringNoCalling feature; defaults server-side to “advisor”. Examples: advisor.
Calling feature; defaults server-side to “advisor”. Examples: advisor.
object_namestringNoThe schema object’s ODCS name (schema[].name) the advice is for. Optional.
The schema object’s ODCS name (schema[].name) the advice is for. Optional.
project_idstringNoThe control-plane project of the run that asks. Optional; with environment, source_slug and object_name it names the object on the call’s row in the advisor call log. When named, the environment the call resolves in must be an environment of this project whose runs dispatch to the calling agent (postAdvise step 2: 403 otherwise, once step 1 has found the advisor enabled).
The control-plane project of the run that asks. Optional; with environment, source_slug and object_name it names the object on the call’s row in the advisor call log. When named, the environment the call resolves in must be an environment of this project whose runs dispatch to the calling agent (postAdvise step 2: 403 otherwise, once step 1 has found the advisor enabled).
source_slugstringNoThe catalog source of the object the advice is for. Optional.
The catalog source of the object the advice is for. Optional.
toon_profilestringYesTOON profile of the source data; capped at 256 KB server-side.
TOON profile of the source data; capped at 256 KB server-side.

Responses  

200 The advice produced by the LLM (outcome answered), or the control plane's typed decision not to ask one (outcome no_answer, with no_answer_reason).

application/json

PropertyTypeRequiredDescription
cache_hitbooleanYesWhether the response was served from the advisor cache.
Whether the response was served from the advisor cache.
call_idstringNoThe call’s row in the advisor call log. Absent when no row is written: with reason disabled (see AdvisorCall for which calls are logged). Present on a cache hit. The agent passes it back as advisor_call_id when it files the classification, which sets the row’s result.
The call’s row in the advisor call log. Absent when no row is written: with reason disabled (see AdvisorCall for which calls are logged). Present on a cache hit. The agent passes it back as advisor_call_id when it files the classification, which sets the row’s result.
input_tokensintegerYesNumber of input tokens consumed.
Number of input tokens consumed.
modelstringYesLLM model that produced the advice. Examples: claude-sonnet-4-6.
LLM model that produced the advice. Examples: claude-sonnet-4-6.
no_answer_reasonAdvisorNoAnswerReasonNo
outcomeAdviseOutcomeYes
output_tokensintegerYesNumber of output tokens generated.
Number of output tokens generated.
pcf_yamlstringYesPCF (pipeline configuration format) YAML produced by the LLM.
PCF (pipeline configuration format) YAML produced by the LLM.
providerstringYesLLM provider that produced the advice. Examples: anthropic.
LLM provider that produced the advice. Examples: anthropic.
400 The request was malformed or failed validation.

application/json

PropertyTypeRequiredDescription
codestringYesStable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
Stable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
fieldstringNoOptional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
Optional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
messagestringYesHuman-readable description of the error. Examples: limit must be between 1 and 100.
Human-readable description of the error. Examples: limit must be between 1 and 100.
401 The request lacks valid credentials.

application/json

PropertyTypeRequiredDescription
codestringYesStable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
Stable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
fieldstringNoOptional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
Optional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
messagestringYesHuman-readable description of the error. Examples: limit must be between 1 and 100.
Human-readable description of the error. Examples: limit must be between 1 and 100.
403 Code permission_denied, at step 2, so only for an organization whose advisor is enabled (step 1): the environment the call resolves in, the one the request names or the api's configured one when it names none, is not assigned to the calling agent (no project environment whose runs dispatch to it), or is not an environment of the project the request names. Nothing is sent and no call-log row is written.

application/json

PropertyTypeRequiredDescription
codestringYesStable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
Stable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
fieldstringNoOptional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
Optional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
messagestringYesHuman-readable description of the error. Examples: limit must be between 1 and 100.
Human-readable description of the error. Examples: limit must be between 1 and 100.
500 An internal error of the control plane. An outage, not a no_answer.

application/json

PropertyTypeRequiredDescription
codestringYesStable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
Stable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
fieldstringNoOptional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
Optional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
messagestringYesHuman-readable description of the error. Examples: limit must be between 1 and 100.
Human-readable description of the error. Examples: limit must be between 1 and 100.
502 The platform key's provider answered with an error. An outage, not a no_answer. A failure on the organization's own key is never a 502, a missing or misconfigured gateway base URL of an own key included: it is no_answer with reason own_key_failed.

application/json

PropertyTypeRequiredDescription
codestringYesStable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
Stable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
fieldstringNoOptional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
Optional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
messagestringYesHuman-readable description of the error. Examples: limit must be between 1 and 100.
Human-readable description of the error. Examples: limit must be between 1 and 100.
503 The control plane could not read the organization's own key from the environment's vault. An outage, not a no_answer.

application/json

PropertyTypeRequiredDescription
codestringYesStable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
Stable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
fieldstringNoOptional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
Optional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
messagestringYesHuman-readable description of the error. Examples: limit must be between 1 and 100.
Human-readable description of the error. Examples: limit must be between 1 and 100.
504 The platform key's provider did not answer in time. An outage, not a no_answer. A timeout on the organization's own key is never a 504: it is no_answer with reason own_key_failed.

application/json

PropertyTypeRequiredDescription
codestringYesStable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
Stable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
fieldstringNoOptional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
Optional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
messagestringYesHuman-readable description of the error. Examples: limit must be between 1 and 100.
Human-readable description of the error. Examples: limit must be between 1 and 100.

Security  

bearer_jwt


GET /v1/platform/orgs/{slug}/advise/allowance  

Get one organization's advisor allowance (platform).

A platform operation for the sysadmin role (ADR-053), which is never a membership role: no customer role holds a platform.* permission. The organization is named in the path, not by X-Tenant-Slug. Returns the same body as getAdvisorAllowance.

Parameters  

NameInRequiredTypeDescription
slugpathYesstringSlug of the organization.
Slug of the organization.

Responses  

200 The organization's allowance.

application/json

PropertyTypeRequiredDescription
allowance_tokensintegerYesThe allowance. Set per organization by a sysadmin (setOrgAdvisorAllowance). Examples: 500000.
The allowance. Set per organization by a sysadmin (setOrgAdvisorAllowance). Examples: 500000.
metered_callsintegerYesThe number of calls metered against the allowance; with used_tokens it gives the average tokens per call, from which a client can estimate the tables the remainder covers. Examples: 40.
The number of calls metered against the allowance; with used_tokens it gives the average tokens per call, from which a client can estimate the tables the remainder covers. Examples: 40.
remaining_tokensintegerYesallowance_tokens minus used_tokens, and never below 0. Examples: 380000.
allowance_tokens minus used_tokens, and never below 0. Examples: 380000.
used_tokensintegerYesTokens metered against the allowance so far. Calls already in flight when the allowance runs out are still metered, so this may exceed allowance_tokens. Examples: 120000.
Tokens metered against the allowance so far. Calls already in flight when the allowance runs out are still metered, so this may exceed allowance_tokens. Examples: 120000.
401 The request lacks valid credentials.

application/json

PropertyTypeRequiredDescription
codestringYesStable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
Stable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
fieldstringNoOptional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
Optional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
messagestringYesHuman-readable description of the error. Examples: limit must be between 1 and 100.
Human-readable description of the error. Examples: limit must be between 1 and 100.
403 The caller is authenticated but not permitted to perform the request.

application/json

PropertyTypeRequiredDescription
codestringYesStable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
Stable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
fieldstringNoOptional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
Optional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
messagestringYesHuman-readable description of the error. Examples: limit must be between 1 and 100.
Human-readable description of the error. Examples: limit must be between 1 and 100.
404 The specified resource was not found.

application/json

PropertyTypeRequiredDescription
codestringYesStable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
Stable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
fieldstringNoOptional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
Optional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
messagestringYesHuman-readable description of the error. Examples: limit must be between 1 and 100.
Human-readable description of the error. Examples: limit must be between 1 and 100.

Security  

bearer_jwt


PUT /v1/platform/orgs/{slug}/advise/allowance  

Set one organization's advisor allowance (platform).

A platform operation for the sysadmin role (ADR-053), which is never a membership role: no customer role holds a platform.* permission. Sets the organization’s free token allowance on the Amfelt platform key. used_tokens is left as it is, so an allowance below it leaves nothing remaining.

Parameters  

NameInRequiredTypeDescription
slugpathYesstringSlug of the organization.
Slug of the organization.

Request body (required)  

application/json

PropertyTypeRequiredDescription
allowance_tokensintegerYesThe new allowance in tokens. 0 stops all metered calls. Examples: 1000000.
The new allowance in tokens. 0 stops all metered calls. Examples: 1000000.

Responses  

200 The organization's allowance after the change.

application/json

PropertyTypeRequiredDescription
allowance_tokensintegerYesThe allowance. Set per organization by a sysadmin (setOrgAdvisorAllowance). Examples: 500000.
The allowance. Set per organization by a sysadmin (setOrgAdvisorAllowance). Examples: 500000.
metered_callsintegerYesThe number of calls metered against the allowance; with used_tokens it gives the average tokens per call, from which a client can estimate the tables the remainder covers. Examples: 40.
The number of calls metered against the allowance; with used_tokens it gives the average tokens per call, from which a client can estimate the tables the remainder covers. Examples: 40.
remaining_tokensintegerYesallowance_tokens minus used_tokens, and never below 0. Examples: 380000.
allowance_tokens minus used_tokens, and never below 0. Examples: 380000.
used_tokensintegerYesTokens metered against the allowance so far. Calls already in flight when the allowance runs out are still metered, so this may exceed allowance_tokens. Examples: 120000.
Tokens metered against the allowance so far. Calls already in flight when the allowance runs out are still metered, so this may exceed allowance_tokens. Examples: 120000.
400 The request was malformed or failed validation.

application/json

PropertyTypeRequiredDescription
codestringYesStable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
Stable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
fieldstringNoOptional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
Optional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
messagestringYesHuman-readable description of the error. Examples: limit must be between 1 and 100.
Human-readable description of the error. Examples: limit must be between 1 and 100.
401 The request lacks valid credentials.

application/json

PropertyTypeRequiredDescription
codestringYesStable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
Stable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
fieldstringNoOptional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
Optional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
messagestringYesHuman-readable description of the error. Examples: limit must be between 1 and 100.
Human-readable description of the error. Examples: limit must be between 1 and 100.
403 The caller is authenticated but not permitted to perform the request.

application/json

PropertyTypeRequiredDescription
codestringYesStable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
Stable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
fieldstringNoOptional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
Optional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
messagestringYesHuman-readable description of the error. Examples: limit must be between 1 and 100.
Human-readable description of the error. Examples: limit must be between 1 and 100.
404 The specified resource was not found.

application/json

PropertyTypeRequiredDescription
codestringYesStable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
Stable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
fieldstringNoOptional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
Optional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
messagestringYesHuman-readable description of the error. Examples: limit must be between 1 and 100.
Human-readable description of the error. Examples: limit must be between 1 and 100.

Security  

bearer_jwt


POST /v1/advise/own-keys/{environment}/test  

Test the organization's own LLM key in one environment.

Sends a minimal fixed request to the provider of the own key registered in the environment, with its saved provider, model and base_url, and reports whether the provider answered. It sends no table structure or profile, is not written to the advisor call log, and is never metered. A failed test is a 200 with ok false and a reason, not an error.

A test is allowed while the advisor is off. It sends no customer data at all, only that minimal fixed probe, and the advisor switch (setAdvisorEnabled) governs whether customer data is sent, which only postAdvise does. So a key can be checked before the advisor is switched on, and testing it switches nothing on.

Parameters  

NameInRequiredTypeDescription
X-Tenant-SlugheaderYesstringSlug of the organization to scope the request to; required for user-authenticated requests.
Slug of the organization to scope the request to; required for user-authenticated requests.
environmentpathYesstringDTAP environment slug whose vault holds the own key; answers 404 when the organization has no such environment.
DTAP environment slug whose vault holds the own key; answers 404 when the organization has no such environment.

Responses  

200 The test's outcome.

application/json

PropertyTypeRequiredDescription
modelstringNoThe model tested; absent with reason not_set. Examples: claude-sonnet-5-5.
The model tested; absent with reason not_set. Examples: claude-sonnet-5-5.
okbooleanYesWhether the provider answered on the own key.
Whether the provider answered on the own key.
providerstringNoThe provider tested; absent with reason not_set. Examples: anthropic.
The provider tested; absent with reason not_set. Examples: anthropic.
reasonAdvisorOwnKeyTestFailureNo
tested_atstringYesWhen the test ran.
When the test ran.
401 The request lacks valid credentials.

application/json

PropertyTypeRequiredDescription
codestringYesStable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
Stable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
fieldstringNoOptional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
Optional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
messagestringYesHuman-readable description of the error. Examples: limit must be between 1 and 100.
Human-readable description of the error. Examples: limit must be between 1 and 100.
403 The caller is authenticated but not permitted to perform the request.

application/json

PropertyTypeRequiredDescription
codestringYesStable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
Stable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
fieldstringNoOptional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
Optional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
messagestringYesHuman-readable description of the error. Examples: limit must be between 1 and 100.
Human-readable description of the error. Examples: limit must be between 1 and 100.
404 The specified resource was not found.

application/json

PropertyTypeRequiredDescription
codestringYesStable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
Stable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
fieldstringNoOptional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
Optional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
messagestringYesHuman-readable description of the error. Examples: limit must be between 1 and 100.
Human-readable description of the error. Examples: limit must be between 1 and 100.
503 The control plane could not read the own key from the environment's vault; the provider was not asked.

application/json

PropertyTypeRequiredDescription
codestringYesStable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
Stable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
fieldstringNoOptional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
Optional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
messagestringYesHuman-readable description of the error. Examples: limit must be between 1 and 100.
Human-readable description of the error. Examples: limit must be between 1 and 100.

Security  

bearer_jwt


PUT /v1/advise/own-keys/{environment}  

Register or replace the organization's own LLM key in one environment.

Stores the organization’s own provider key in the environment’s vault at {environment}/llm/{provider}, together with the provider settings its calls use (provider, model, base_url), as one change that records the caller as changed_by. From then on that environment’s advise calls run on this key and are never metered. api_key may be left out to keep the key already registered there for the same provider, for example to change only the model. Registering a key for another provider deletes the environment’s previous own key, so an environment has at most one. The key is never returned: the response is the environment’s settings read, with own_key set. Registering a key does not switch the advisor on. This is the only operation that changes a registered own key’s provider, model or base_url; updateAdviseConfig answers 409 rather than change them.

Parameters  

NameInRequiredTypeDescription
X-Tenant-SlugheaderYesstringSlug of the organization to scope the request to; required for user-authenticated requests.
Slug of the organization to scope the request to; required for user-authenticated requests.
environmentpathYesstringDTAP environment slug whose vault holds the own key; answers 404 when the organization has no such environment.
DTAP environment slug whose vault holds the own key; answers 404 when the organization has no such environment.

Request body (required)  

application/json

PropertyTypeRequiredDescription
api_keystringNoThe provider API key. Write-only: stored in the environment’s vault and never returned by any customer-facing or advisor operation. Required when the environment has no own key for this provider (400 otherwise); absent keeps that key. Outside this contract and unchanged by it, resolveSecret with the operator-bootstrap token is not limited to particular vault refs (it stays organization-wide, gated by the policy engine), so this key’s {environment}/llm/{provider} ref is within its reach. Likewise outside it, registerSecret and updateSecret with the operator-bootstrap token are organization-wide, so they can write a secret at that ref without setAdvisorOwnKey; this contract does not govern such a write.
The provider API key. Write-only: stored in the environment’s vault and never returned by any customer-facing or advisor operation. Required when the environment has no own key for this provider (400 otherwise); absent keeps that key. Outside this contract and unchanged by it, resolveSecret with the operator-bootstrap token is not limited to particular vault refs (it stays organization-wide, gated by the policy engine), so this key’s {environment}/llm/{provider} ref is within its reach. Likewise outside it, registerSecret and updateSecret with the operator-bootstrap token are organization-wide, so they can write a secret at that ref without setAdvisorOwnKey; this contract does not govern such a write.
base_urlstringNoOptional OpenAI-compatible gateway base URL (ADR-091). Only meaningful for provider gateway. A default gateway exists only where this deployment pins a gateway base URL: there an empty or absent value uses the pinned one, and the pinned one wins over the value saved here. A deployment that pins none refuses an empty or absent base_url for provider gateway with 400 (AdvisorProvider.requires_base_url). Examples: http://litellm:4000/v1.
Optional OpenAI-compatible gateway base URL (ADR-091). Only meaningful for provider gateway. A default gateway exists only where this deployment pins a gateway base URL: there an empty or absent value uses the pinned one, and the pinned one wins over the value saved here. A deployment that pins none refuses an empty or absent base_url for provider gateway with 400 (AdvisorProvider.requires_base_url). Examples: http://litellm:4000/v1.
modelstringYesLLM model; validated against the server-side allowlist for the provider. Examples: claude-sonnet-5-5.
LLM model; validated against the server-side allowlist for the provider. Examples: claude-sonnet-5-5.
providerstringYesLLM provider; validated against the server-side allowlist (e.g. anthropic, openai, gateway for an OpenAI-compatible gateway endpoint). The key is stored at {environment}/llm/{provider}. Examples: anthropic.
LLM provider; validated against the server-side allowlist (e.g. anthropic, openai, gateway for an OpenAI-compatible gateway endpoint). The key is stored at {environment}/llm/{provider}. Examples: anthropic.

Responses  

200 The environment's advisor settings after the save; never the key.

application/json

PropertyTypeRequiredDescription
base_urlstringNoThe own key’s OpenAI-compatible gateway base URL (ADR-091), as saved. Only meaningful for provider gateway; absent while provider_source is platform. A default gateway exists only where this deployment pins a gateway base URL: there an empty value uses the pinned one, and the pinned one wins over a saved value. A deployment that pins none refuses an empty base_url for provider gateway when an own key is registered (setAdvisorOwnKey). Examples: http://litellm:4000/v1.
The own key’s OpenAI-compatible gateway base URL (ADR-091), as saved. Only meaningful for provider gateway; absent while provider_source is platform. A default gateway exists only where this deployment pins a gateway base URL: there an empty value uses the pinned one, and the pinned one wins over a saved value. A deployment that pins none refuses an empty base_url for provider gateway when an own key is registered (setAdvisorOwnKey). Examples: http://litellm:4000/v1.
changed_at[string null]NoWhen this environment’s own key or provider settings last changed. Always present on the wire; null when never.
When this environment’s own key or provider settings last changed. Always present on the wire; null when never.
changed_byNoThe account that last changed this environment’s own key or its provider settings (setAdvisorOwnKey, removeAdvisorOwnKey, updateAdviseConfig). Always present on the wire; null when none was ever changed.
The account that last changed this environment’s own key or its provider settings (setAdvisorOwnKey, removeAdvisorOwnKey, updateAdviseConfig). Always present on the wire; null when none was ever changed.
disclosure_version[string null]NoThe version of the disclosure shown to the account that last switched the advisor on or off (AdvisorEnabledUpdate). Always present on the wire; null when the organization never chose. Examples: advisor-disclosure-2026-10-17.
The version of the disclosure shown to the account that last switched the advisor on or off (AdvisorEnabledUpdate). Always present on the wire; null when the organization never chose. Examples: advisor-disclosure-2026-10-17.
enabledbooleanYesWhether the advisor may be asked for this organization. One value for the whole organization, the same in every environment’s read; the provider settings below are per environment. Off by default: false for an organization that never chose, and only setAdvisorEnabled by an owner or admin turns it on. No missing row, registered key, allowance or provider default reads as true. When false, no advisor call leaves the organization on either key.
Whether the advisor may be asked for this organization. One value for the whole organization, the same in every environment’s read; the provider settings below are per environment. Off by default: false for an organization that never chose, and only setAdvisorEnabled by an owner or admin turns it on. No missing row, registered key, allowance or provider default reads as true. When false, no advisor call leaves the organization on either key.
enabled_changed_at[string null]NoWhen the organization’s advisor was last switched on or off. Always present on the wire; null when never.
When the organization’s advisor was last switched on or off. Always present on the wire; null when never.
enabled_changed_byNoThe account that last switched the organization’s advisor on or off. Always present on the wire; null when the organization never chose.
The account that last switched the organization’s advisor on or off. Always present on the wire; null when the organization never chose.
enabled_reasonNoWhere the advisor was last switched on or off: onboarding or settings (AdvisorEnabledUpdate.reason). Always present on the wire; null when the organization never chose.
Where the advisor was last switched on or off: onboarding or settings (AdvisorEnabledUpdate.reason). Always present on the wire; null when the organization never chose.
envstringYesDTAP environment this config applies to. Examples: production.
DTAP environment this config applies to. Examples: production.
modelstringYesThe LLM model this environment’s calls run on: the own key’s saved model while provider_source is own_key, the organization’s platform-key model while it is platform. Examples: claude-sonnet-5-5.
The LLM model this environment’s calls run on: the own key’s saved model while provider_source is own_key, the organization’s platform-key model while it is platform. Examples: claude-sonnet-5-5.
own_keyAdvisorOwnKeyStatusYes
providerstringYesThe LLM provider this environment’s calls run on: the own key’s while provider_source is own_key, the platform key’s while it is platform (e.g. anthropic, openai, gateway for an OpenAI-compatible gateway endpoint). Examples: anthropic.
The LLM provider this environment’s calls run on: the own key’s while provider_source is own_key, the platform key’s while it is platform (e.g. anthropic, openai, gateway for an OpenAI-compatible gateway endpoint). Examples: anthropic.
provider_sourceAdvisorProviderSourceYes
vault_refstringYesInformational vault path where the organization’s own LLM API key is (or would be) stored for this environment and provider. The Amfelt platform key is never stored in an organization vault. Examples: production/llm/anthropic.
Informational vault path where the organization’s own LLM API key is (or would be) stored for this environment and provider. The Amfelt platform key is never stored in an organization vault. Examples: production/llm/anthropic.
400 The request was malformed or failed validation.

application/json

PropertyTypeRequiredDescription
codestringYesStable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
Stable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
fieldstringNoOptional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
Optional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
messagestringYesHuman-readable description of the error. Examples: limit must be between 1 and 100.
Human-readable description of the error. Examples: limit must be between 1 and 100.
401 The request lacks valid credentials.

application/json

PropertyTypeRequiredDescription
codestringYesStable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
Stable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
fieldstringNoOptional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
Optional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
messagestringYesHuman-readable description of the error. Examples: limit must be between 1 and 100.
Human-readable description of the error. Examples: limit must be between 1 and 100.
403 The caller is authenticated but not permitted to perform the request.

application/json

PropertyTypeRequiredDescription
codestringYesStable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
Stable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
fieldstringNoOptional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
Optional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
messagestringYesHuman-readable description of the error. Examples: limit must be between 1 and 100.
Human-readable description of the error. Examples: limit must be between 1 and 100.
404 The specified resource was not found.

application/json

PropertyTypeRequiredDescription
codestringYesStable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
Stable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
fieldstringNoOptional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
Optional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
messagestringYesHuman-readable description of the error. Examples: limit must be between 1 and 100.
Human-readable description of the error. Examples: limit must be between 1 and 100.

Security  

bearer_jwt


DELETE /v1/advise/own-keys/{environment}  

Remove the organization's own LLM key from one environment.

Deletes the organization’s own key from the environment’s vault (Remove my key on the Advisor tab). From then on that environment’s advise calls run on the Amfelt platform key and count against the free allowance. Idempotent: an environment without an own key answers 200 with its settings unchanged.

Parameters  

NameInRequiredTypeDescription
X-Tenant-SlugheaderYesstringSlug of the organization to scope the request to; required for user-authenticated requests.
Slug of the organization to scope the request to; required for user-authenticated requests.
environmentpathYesstringDTAP environment slug whose vault holds the own key; answers 404 when the organization has no such environment.
DTAP environment slug whose vault holds the own key; answers 404 when the organization has no such environment.

Responses  

200 The environment's advisor settings after the removal, with own_key not_set.

application/json

PropertyTypeRequiredDescription
base_urlstringNoThe own key’s OpenAI-compatible gateway base URL (ADR-091), as saved. Only meaningful for provider gateway; absent while provider_source is platform. A default gateway exists only where this deployment pins a gateway base URL: there an empty value uses the pinned one, and the pinned one wins over a saved value. A deployment that pins none refuses an empty base_url for provider gateway when an own key is registered (setAdvisorOwnKey). Examples: http://litellm:4000/v1.
The own key’s OpenAI-compatible gateway base URL (ADR-091), as saved. Only meaningful for provider gateway; absent while provider_source is platform. A default gateway exists only where this deployment pins a gateway base URL: there an empty value uses the pinned one, and the pinned one wins over a saved value. A deployment that pins none refuses an empty base_url for provider gateway when an own key is registered (setAdvisorOwnKey). Examples: http://litellm:4000/v1.
changed_at[string null]NoWhen this environment’s own key or provider settings last changed. Always present on the wire; null when never.
When this environment’s own key or provider settings last changed. Always present on the wire; null when never.
changed_byNoThe account that last changed this environment’s own key or its provider settings (setAdvisorOwnKey, removeAdvisorOwnKey, updateAdviseConfig). Always present on the wire; null when none was ever changed.
The account that last changed this environment’s own key or its provider settings (setAdvisorOwnKey, removeAdvisorOwnKey, updateAdviseConfig). Always present on the wire; null when none was ever changed.
disclosure_version[string null]NoThe version of the disclosure shown to the account that last switched the advisor on or off (AdvisorEnabledUpdate). Always present on the wire; null when the organization never chose. Examples: advisor-disclosure-2026-10-17.
The version of the disclosure shown to the account that last switched the advisor on or off (AdvisorEnabledUpdate). Always present on the wire; null when the organization never chose. Examples: advisor-disclosure-2026-10-17.
enabledbooleanYesWhether the advisor may be asked for this organization. One value for the whole organization, the same in every environment’s read; the provider settings below are per environment. Off by default: false for an organization that never chose, and only setAdvisorEnabled by an owner or admin turns it on. No missing row, registered key, allowance or provider default reads as true. When false, no advisor call leaves the organization on either key.
Whether the advisor may be asked for this organization. One value for the whole organization, the same in every environment’s read; the provider settings below are per environment. Off by default: false for an organization that never chose, and only setAdvisorEnabled by an owner or admin turns it on. No missing row, registered key, allowance or provider default reads as true. When false, no advisor call leaves the organization on either key.
enabled_changed_at[string null]NoWhen the organization’s advisor was last switched on or off. Always present on the wire; null when never.
When the organization’s advisor was last switched on or off. Always present on the wire; null when never.
enabled_changed_byNoThe account that last switched the organization’s advisor on or off. Always present on the wire; null when the organization never chose.
The account that last switched the organization’s advisor on or off. Always present on the wire; null when the organization never chose.
enabled_reasonNoWhere the advisor was last switched on or off: onboarding or settings (AdvisorEnabledUpdate.reason). Always present on the wire; null when the organization never chose.
Where the advisor was last switched on or off: onboarding or settings (AdvisorEnabledUpdate.reason). Always present on the wire; null when the organization never chose.
envstringYesDTAP environment this config applies to. Examples: production.
DTAP environment this config applies to. Examples: production.
modelstringYesThe LLM model this environment’s calls run on: the own key’s saved model while provider_source is own_key, the organization’s platform-key model while it is platform. Examples: claude-sonnet-5-5.
The LLM model this environment’s calls run on: the own key’s saved model while provider_source is own_key, the organization’s platform-key model while it is platform. Examples: claude-sonnet-5-5.
own_keyAdvisorOwnKeyStatusYes
providerstringYesThe LLM provider this environment’s calls run on: the own key’s while provider_source is own_key, the platform key’s while it is platform (e.g. anthropic, openai, gateway for an OpenAI-compatible gateway endpoint). Examples: anthropic.
The LLM provider this environment’s calls run on: the own key’s while provider_source is own_key, the platform key’s while it is platform (e.g. anthropic, openai, gateway for an OpenAI-compatible gateway endpoint). Examples: anthropic.
provider_sourceAdvisorProviderSourceYes
vault_refstringYesInformational vault path where the organization’s own LLM API key is (or would be) stored for this environment and provider. The Amfelt platform key is never stored in an organization vault. Examples: production/llm/anthropic.
Informational vault path where the organization’s own LLM API key is (or would be) stored for this environment and provider. The Amfelt platform key is never stored in an organization vault. Examples: production/llm/anthropic.
401 The request lacks valid credentials.

application/json

PropertyTypeRequiredDescription
codestringYesStable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
Stable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
fieldstringNoOptional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
Optional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
messagestringYesHuman-readable description of the error. Examples: limit must be between 1 and 100.
Human-readable description of the error. Examples: limit must be between 1 and 100.
403 The caller is authenticated but not permitted to perform the request.

application/json

PropertyTypeRequiredDescription
codestringYesStable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
Stable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
fieldstringNoOptional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
Optional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
messagestringYesHuman-readable description of the error. Examples: limit must be between 1 and 100.
Human-readable description of the error. Examples: limit must be between 1 and 100.
404 The specified resource was not found.

application/json

PropertyTypeRequiredDescription
codestringYesStable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
Stable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
fieldstringNoOptional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
Optional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
messagestringYesHuman-readable description of the error. Examples: limit must be between 1 and 100.
Human-readable description of the error. Examples: limit must be between 1 and 100.

Security  

bearer_jwt


Schemas  

Llm Usage List  

type: LlmUsageList

A page of LLM-usage rows plus the page’s aggregate cost.

PropertyTypeRequiredDescription
dataLlmUsage []YesThe page of usage rows.
The page of usage rows.
next_cursor[string null]NoOpaque cursor for the next page, or null when this is the final page. Examples: eyJpZCI6OTk5fQ.
Opaque cursor for the next page, or null when this is the final page. Examples: eyJpZCI6OTk5fQ.
total_cost_usdnumberYesSum of cost_usd across the returned rows; per-page aggregate.
Sum of cost_usd across the returned rows; per-page aggregate.

Llm Usage  

type: LlmUsage

A single LLM-usage row.

PropertyTypeRequiredDescription
cache_hitbooleanYesWhether the event was served from the advisor cache.
Whether the event was served from the advisor cache.
cost_usdnumberYesEstimated USD cost of the event.
Estimated USD cost of the event.
created_atstringYesTimestamp the usage event was recorded.
Timestamp the usage event was recorded.
featurestringYesCalling feature that produced the event. Examples: advisor.
Calling feature that produced the event. Examples: advisor.
input_tokensintegerYesNumber of input tokens consumed.
Number of input tokens consumed.
modelstringYesLLM model.
LLM model.
output_tokensintegerYesNumber of output tokens generated.
Number of output tokens generated.
providerstringYesLLM provider.
LLM provider.

Error  

type: Error

The standard error envelope returned by every non-2xx response.

PropertyTypeRequiredDescription
codestringYesStable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
Stable, snake_case token identifying the error condition. See ErrorCode for the api’s canonical named vocabulary — this field is deliberately not restricted to it, since handlers may emit other ad-hoc codes not listed there (e.g. not_implemented). Examples: invalid_argument.
fieldstringNoOptional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
Optional hint identifying the request field the error refers to, in snake_case (e.g. “slug”, “display_name”, “token”). Set by handlers that validate multiple fields and want to enable field-targeted UX in clients. Absent when the error does not map to a single field. Examples: slug.
messagestringYesHuman-readable description of the error. Examples: limit must be between 1 and 100.
Human-readable description of the error. Examples: limit must be between 1 and 100.

Advisor Provider List  

type: AdvisorProviderList

The providers an own key may use (listAdvisorProviders), and the provider and model of the organization’s calls on the Amfelt platform key.

PropertyTypeRequiredDescription
dataAdvisorProvider []YesThe providers an own key may be registered for.
The providers an own key may be registered for.
platform_modelstringYesThe model of the caller’s organization’s calls on the platform key: LlmConfig.model while provider_source is platform. Named whether or not this deployment has a platform key configured; without one, a call on the platform key answers no_answer with reason no_provider. Examples: claude-sonnet-5-5.
The model of the caller’s organization’s calls on the platform key: LlmConfig.model while provider_source is platform. Named whether or not this deployment has a platform key configured; without one, a call on the platform key answers no_answer with reason no_provider. Examples: claude-sonnet-5-5.
platform_providerstringYesThe provider of the Amfelt platform key’s calls. Examples: anthropic.
The provider of the Amfelt platform key’s calls. Examples: anthropic.

Advisor Provider  

type: AdvisorProvider

One provider an own key may be registered for, and what it accepts.

PropertyTypeRequiredDescription
any_modelbooleanYesTrue for a provider that fronts an open model set (gateway, ADR-091): any non-empty model is accepted, and models lists none.
True for a provider that fronts an open model set (gateway, ADR-091): any non-empty model is accepted, and models lists none.
modelsstring[]YesThe models setAdvisorOwnKey accepts for this provider, from the server-side allowlist. Empty when any_model is true. Examples: ["claude-sonnet-5-5"].
The models setAdvisorOwnKey accepts for this provider, from the server-side allowlist. Empty when any_model is true. Examples: ["claude-sonnet-5-5"].
providerstringYesThe provider, as setAdvisorOwnKey takes it. Examples: anthropic.
The provider, as setAdvisorOwnKey takes it. Examples: anthropic.
requires_base_urlbooleanYesWhether setAdvisorOwnKey for this provider must carry a base_url on this deployment: true only for gateway on a deployment that pins no gateway base URL, since only a pinned one is a default. base_url is meaningful only for gateway.
Whether setAdvisorOwnKey for this provider must carry a base_url on this deployment: true only for gateway on a deployment that pins no gateway base URL, since only a pinned one is a default. base_url is meaningful only for gateway.

Advisor Notice  

type: AdvisorNotice

The caller’s state of the one-time advisor invitation in one organization.

PropertyTypeRequiredDescription
dismissed_at[string null]YesWhen the caller dismissed the invitation. Always present on the wire; null while not dismissed.
When the caller dismissed the invitation. Always present on the wire; null while not dismissed.
showbooleanYesWhether the app shows the invitation to the caller now: true only for an owner or admin of an organization with no recorded choice at all (never switched on or off), who has not dismissed it.
Whether the app shows the invitation to the caller now: true only for an owner or admin of an organization with no recorded choice at all (never switched on or off), who has not dismissed it.

Advisor Enabled Update  

type: AdvisorEnabledUpdate

The payload for setAdvisorEnabled.

PropertyTypeRequiredDescription
disclosure_versionstringYesThe version of the disclosure the person saw with the choice: what the advisor sends to Claude (Anthropic) and the free allowance. The api records it with the choice and returns it on reads. Examples: advisor-disclosure-2026-10-17.
The version of the disclosure the person saw with the choice: what the advisor sends to Claude (Anthropic) and the free allowance. The api records it with the choice and returns it on reads. Examples: advisor-disclosure-2026-10-17.
enabledbooleanYesSwitches the advisor on (true) or off (false) for the whole organization.
Switches the advisor on (true) or off (false) for the whole organization.
reasonAdvisorEnabledReasonNo

Advisor Enabled Reason  

type: AdvisorEnabledReason

Where the switch was set, recorded with the change: onboarding (the step that creates the organization) or settings (the Advisor tab). Absent in AdvisorEnabledUpdate means settings. Read back as enabled_reason on AdvisorEnablement and LlmConfig.

Advisor Enablement  

type: AdvisorEnablement

The organization’s advisor switch and its last change, as setAdvisorEnabled answers it. The same fields, with the same meaning, are on LlmConfig.

PropertyTypeRequiredDescription
disclosure_version[string null]YesThe version of the disclosure shown with the last choice; null when the organization never chose. Examples: advisor-disclosure-2026-10-17.
The version of the disclosure shown with the last choice; null when the organization never chose. Examples: advisor-disclosure-2026-10-17.
enabledbooleanYesWhether the advisor may be asked for this organization, on either key.
Whether the advisor may be asked for this organization, on either key.
enabled_changed_at[string null]YesWhen the organization’s advisor was last switched on or off; null when never.
When the organization’s advisor was last switched on or off; null when never.
enabled_changed_byYesThe account that last switched the organization’s advisor on or off; null when the organization never chose.
The account that last switched the organization’s advisor on or off; null when the organization never chose.
enabled_reasonYesWhere the last choice was made: onboarding or settings (AdvisorEnabledUpdate.reason); null when the organization never chose.
Where the last choice was made: onboarding or settings (AdvisorEnabledUpdate.reason); null when the organization never chose.

Schedule Actor  

type: ScheduleActor

The account that performed an operator action on a schedule.

PropertyTypeRequiredDescription
display_namestringYesThe account’s display name, resolved when the state is read. Examples: Anna.
The account’s display name, resolved when the state is read. Examples: Anna.
idstringYesAccount identifier.
Account identifier.

Llm Config  

type: LlmConfig

The advisor settings of an organization as read for one environment: the organization-wide on/off switch (enabled and its last change), and that environment’s own key and provider (own_key, provider_source, provider, model and their last change), since the own key lives in the environment’s vault at vault_ref. Never carries a key.

PropertyTypeRequiredDescription
base_urlstringNoThe own key’s OpenAI-compatible gateway base URL (ADR-091), as saved. Only meaningful for provider gateway; absent while provider_source is platform. A default gateway exists only where this deployment pins a gateway base URL: there an empty value uses the pinned one, and the pinned one wins over a saved value. A deployment that pins none refuses an empty base_url for provider gateway when an own key is registered (setAdvisorOwnKey). Examples: http://litellm:4000/v1.
The own key’s OpenAI-compatible gateway base URL (ADR-091), as saved. Only meaningful for provider gateway; absent while provider_source is platform. A default gateway exists only where this deployment pins a gateway base URL: there an empty value uses the pinned one, and the pinned one wins over a saved value. A deployment that pins none refuses an empty base_url for provider gateway when an own key is registered (setAdvisorOwnKey). Examples: http://litellm:4000/v1.
changed_at[string null]NoWhen this environment’s own key or provider settings last changed. Always present on the wire; null when never.
When this environment’s own key or provider settings last changed. Always present on the wire; null when never.
changed_byNoThe account that last changed this environment’s own key or its provider settings (setAdvisorOwnKey, removeAdvisorOwnKey, updateAdviseConfig). Always present on the wire; null when none was ever changed.
The account that last changed this environment’s own key or its provider settings (setAdvisorOwnKey, removeAdvisorOwnKey, updateAdviseConfig). Always present on the wire; null when none was ever changed.
disclosure_version[string null]NoThe version of the disclosure shown to the account that last switched the advisor on or off (AdvisorEnabledUpdate). Always present on the wire; null when the organization never chose. Examples: advisor-disclosure-2026-10-17.
The version of the disclosure shown to the account that last switched the advisor on or off (AdvisorEnabledUpdate). Always present on the wire; null when the organization never chose. Examples: advisor-disclosure-2026-10-17.
enabledbooleanYesWhether the advisor may be asked for this organization. One value for the whole organization, the same in every environment’s read; the provider settings below are per environment. Off by default: false for an organization that never chose, and only setAdvisorEnabled by an owner or admin turns it on. No missing row, registered key, allowance or provider default reads as true. When false, no advisor call leaves the organization on either key.
Whether the advisor may be asked for this organization. One value for the whole organization, the same in every environment’s read; the provider settings below are per environment. Off by default: false for an organization that never chose, and only setAdvisorEnabled by an owner or admin turns it on. No missing row, registered key, allowance or provider default reads as true. When false, no advisor call leaves the organization on either key.
enabled_changed_at[string null]NoWhen the organization’s advisor was last switched on or off. Always present on the wire; null when never.
When the organization’s advisor was last switched on or off. Always present on the wire; null when never.
enabled_changed_byNoThe account that last switched the organization’s advisor on or off. Always present on the wire; null when the organization never chose.
The account that last switched the organization’s advisor on or off. Always present on the wire; null when the organization never chose.
enabled_reasonNoWhere the advisor was last switched on or off: onboarding or settings (AdvisorEnabledUpdate.reason). Always present on the wire; null when the organization never chose.
Where the advisor was last switched on or off: onboarding or settings (AdvisorEnabledUpdate.reason). Always present on the wire; null when the organization never chose.
envstringYesDTAP environment this config applies to. Examples: production.
DTAP environment this config applies to. Examples: production.
modelstringYesThe LLM model this environment’s calls run on: the own key’s saved model while provider_source is own_key, the organization’s platform-key model while it is platform. Examples: claude-sonnet-5-5.
The LLM model this environment’s calls run on: the own key’s saved model while provider_source is own_key, the organization’s platform-key model while it is platform. Examples: claude-sonnet-5-5.
own_keyAdvisorOwnKeyStatusYes
providerstringYesThe LLM provider this environment’s calls run on: the own key’s while provider_source is own_key, the platform key’s while it is platform (e.g. anthropic, openai, gateway for an OpenAI-compatible gateway endpoint). Examples: anthropic.
The LLM provider this environment’s calls run on: the own key’s while provider_source is own_key, the platform key’s while it is platform (e.g. anthropic, openai, gateway for an OpenAI-compatible gateway endpoint). Examples: anthropic.
provider_sourceAdvisorProviderSourceYes
vault_refstringYesInformational vault path where the organization’s own LLM API key is (or would be) stored for this environment and provider. The Amfelt platform key is never stored in an organization vault. Examples: production/llm/anthropic.
Informational vault path where the organization’s own LLM API key is (or would be) stored for this environment and provider. The Amfelt platform key is never stored in an organization vault. Examples: production/llm/anthropic.

Advisor Own Key Status  

type: AdvisorOwnKeyStatus

Whether an own key is registered at vault_ref. The key itself is never returned.

Advisor Provider Source  

type: AdvisorProviderSource

Which key an advisor call runs on. In an environment’s settings (LlmConfig.provider_source) it is derived, never saved and never sent in a write: own_key while an own key is registered in the environment’s vault at vault_ref (setAdvisorOwnKey), platform otherwise (never registered, or removed with removeAdvisorOwnKey). platform: the Amfelt platform key, metered against the organization’s free token allowance; the provider is the platform key’s and the model the organization’s platform model (AdvisorProviderList). own_key: the organization’s own key, never metered; when its provider refuses or fails on it the call is a no_answer with reason own_key_failed and never falls back to the platform key.

Llm Config Update  

type: LlmConfigUpdate

The payload for PUT /v1/advise/config: the saved provider settings of the environment env names. While an own key is registered there they must equal that key’s provider, model and base_url, which only setAdvisorOwnKey changes (409 otherwise). It carries neither the on/off switch (setAdvisorEnabled) nor the key source, which is derived from whether an own key is registered (AdvisorProviderSource).

PropertyTypeRequiredDescription
base_urlstringNoOptional OpenAI-compatible gateway base URL (ADR-091) of the own key. Only meaningful for provider gateway. A default gateway exists only where this deployment pins a gateway base URL: there an empty or absent value uses the pinned one, and the pinned one wins over the value saved here. A deployment that pins none has no default gateway, so there an own key on provider gateway always has a base_url (setAdvisorOwnKey refuses an empty one). Refused with 400 when no own key is registered in this environment: only an own key’s calls use it. While one is registered it must equal that key’s base_url (409 otherwise). Examples: http://litellm:4000/v1.
Optional OpenAI-compatible gateway base URL (ADR-091) of the own key. Only meaningful for provider gateway. A default gateway exists only where this deployment pins a gateway base URL: there an empty or absent value uses the pinned one, and the pinned one wins over the value saved here. A deployment that pins none has no default gateway, so there an own key on provider gateway always has a base_url (setAdvisorOwnKey refuses an empty one). Refused with 400 when no own key is registered in this environment: only an own key’s calls use it. While one is registered it must equal that key’s base_url (409 otherwise). Examples: http://litellm:4000/v1.
envstringNoDTAP environment; defaults server-side to the api’s configured environment. Examples: production.
DTAP environment; defaults server-side to the api’s configured environment. Examples: production.
modelstringYesLLM model; validated against the server-side allowlist for the provider. Examples: claude-sonnet-4-6.
LLM model; validated against the server-side allowlist for the provider. Examples: claude-sonnet-4-6.
providerstringYesLLM provider; validated against the server-side allowlist (e.g. anthropic, openai, gateway for an OpenAI-compatible gateway endpoint). Examples: anthropic.
LLM provider; validated against the server-side allowlist (e.g. anthropic, openai, gateway for an OpenAI-compatible gateway endpoint). Examples: anthropic.

Advisor Call List  

type: AdvisorCallList

A page of an organization’s advisor calls, newest first.

PropertyTypeRequiredDescription
dataAdvisorCall []YesThe page of calls.
The page of calls.
next_cursor[string null]NoOpaque cursor for the next page, or null when this is the final page.
Opaque cursor for the next page, or null when this is the final page.

Advisor Call  

type: AdvisorCall

One row of an organization’s advisor call log. The call log holds a row only for an advise that passed postAdvise step 2 and was answered with outcome answered (a cache hit included) or with a planned no-answer with reason no_provider, allowance_exhausted or own_key_failed. An advise of a disabled organization (reason disabled) and a control-plane failure (5xx) write no row, and neither does a request refused with 403.

PropertyTypeRequiredDescription
created_atstringYesWhen the call was made.
When the call was made.
environment[string null]NoThe DTAP environment of the run that asked, when the request named it.
The DTAP environment of the run that asked, when the request named it.
idstringYesThe call’s id; Advice.call_id of the advise response.
The call’s id; Advice.call_id of the advise response.
input_tokensintegerYesInput tokens the provider reported; 0 when no provider was asked.
Input tokens the provider reported; 0 when no provider was asked.
meteredbooleanYesWhether the call counted against the allowance: true only for a call on the platform key that reached the provider. A call on an own key and a cache hit are never metered.
Whether the call counted against the allowance: true only for a call on the platform key that reached the provider. A call on an own key and a cache hit are never metered.
modelstringNoThe model asked, or whose cached answer was served; absent when none resolved. Examples: claude-sonnet-5-5.
The model asked, or whose cached answer was served; absent when none resolved. Examples: claude-sonnet-5-5.
no_answer_reasonNoSet exactly when result is no_answer: no_provider, allowance_exhausted or own_key_failed. Never disabled, since an advise of a disabled organization writes no row.
Set exactly when result is no_answer: no_provider, allowance_exhausted or own_key_failed. Never disabled, since an advise of a disabled organization writes no row.
object_name[string null]NoThe schema object the call was about, when the request named it.
The schema object the call was about, when the request named it.
output_tokensintegerYesOutput tokens the provider reported; 0 when no provider was asked.
Output tokens the provider reported; 0 when no provider was asked.
project_id[string null]NoThe project of the run that asked, when the request named it.
The project of the run that asked, when the request named it.
providerstringNoThe provider asked, or whose cached answer was served; absent when none resolved. Examples: anthropic.
The provider asked, or whose cached answer was served; absent when none resolved. Examples: anthropic.
provider_sourceYesThe key the call was resolved to (postAdvise, step 3), as the call log records it: own_key while the environment had an own key registered, platform otherwise, a cache hit included. Set on every row the api writes.
The key the call was resolved to (postAdvise, step 3), as the call log records it: own_key while the environment had an own key registered, platform otherwise, a cache hit included. Set on every row the api writes.
resultYesWhat came of the call. Always present on the wire. null means exactly this: the call was answered (outcome answered, a cache hit included) and no classification is stored with this call’s id, because the agent has not filed one or its filing was skipped (IngestCatalogClassificationsResult.skipped). A no-answer row is written with result no_answer at once.
What came of the call. Always present on the wire. null means exactly this: the call was answered (outcome answered, a cache hit included) and no classification is stored with this call’s id, because the agent has not filed one or its filing was skipped (IngestCatalogClassificationsResult.skipped). A no-answer row is written with result no_answer at once.
source_slug[string null]NoThe catalog source of the object, when the request named it.
The catalog source of the object, when the request named it.

Advisor No Answer Reason  

type: AdvisorNoAnswerReason

Why there is no answer. disabled: the advisor is off for the organization, or was never switched on; nothing was sent. Disabled is a normal product path, not a wait: the agent loads the object’s history in its resolved history mode (the job’s, or the default) without a classification. With every other reason the object stops after staging and waits for classification. own_key_failed: the environment has an own key and its provider refused or failed on it (an invalid key, its quota, an outage or a timeout of its provider); the platform key is never used in its place. allowance_exhausted: the environment has no own key, and the organization’s free token allowance on the platform key is used up; nothing was sent. no_provider: the environment has no own key, and this deployment has no platform key configured; nothing was sent.

Advisor Call Result  

type: AdvisorCallResult

What came of an advisor call, as the api recorded it. auto_applied: the answer was filed with the call’s id and stored as a classification approved by the advisor. awaiting_approval: the answer was filed with the call’s id and stored as a proposal, which waits for a person. no_answer: the call had a planned no-answer with reason no_provider, allowance_exhausted or own_key_failed (see no_answer_reason), and the object waits for classification. An advise of a disabled organization is not logged, so disabled is never a call’s result. No value says whether a run went on to load history or bridge; the run report says that.

Advisor Allowance  

type: AdvisorAllowance

An organization’s free advisor token allowance on the Amfelt platform key. Tokens are the provider’s reported input plus output tokens of each metered call.

PropertyTypeRequiredDescription
allowance_tokensintegerYesThe allowance. Set per organization by a sysadmin (setOrgAdvisorAllowance). Examples: 500000.
The allowance. Set per organization by a sysadmin (setOrgAdvisorAllowance). Examples: 500000.
metered_callsintegerYesThe number of calls metered against the allowance; with used_tokens it gives the average tokens per call, from which a client can estimate the tables the remainder covers. Examples: 40.
The number of calls metered against the allowance; with used_tokens it gives the average tokens per call, from which a client can estimate the tables the remainder covers. Examples: 40.
remaining_tokensintegerYesallowance_tokens minus used_tokens, and never below 0. Examples: 380000.
allowance_tokens minus used_tokens, and never below 0. Examples: 380000.
used_tokensintegerYesTokens metered against the allowance so far. Calls already in flight when the allowance runs out are still metered, so this may exceed allowance_tokens. Examples: 120000.
Tokens metered against the allowance so far. Calls already in flight when the allowance runs out are still metered, so this may exceed allowance_tokens. Examples: 120000.

Advise Request  

type: AdviseRequest

The payload for POST /v1/advise.

PropertyTypeRequiredDescription
contract_yamlstringYesODCS contract YAML; capped at 512 KB server-side.
ODCS contract YAML; capped at 512 KB server-side.
environmentstringNoThe DTAP environment of the run that asks. It selects the environment whose own key and provider settings resolve the call (postAdvise), and is recorded on the call’s row in the advisor call log. Optional for compatibility: absent, the api’s configured environment resolves the call, as it did before this field. Named or not, the environment the call resolves in must be a project environment whose runs dispatch to the calling agent (setProjectEnvironmentAgent). This is postAdvise step 2, after enablement: a disabled organization’s call answers 200 no_answer with reason disabled at step 1, before this check. An enabled organization’s call that fails it answers 403 (code permission_denied) and sends nothing. An agent built on this contract sends it. Examples: development.
The DTAP environment of the run that asks. It selects the environment whose own key and provider settings resolve the call (postAdvise), and is recorded on the call’s row in the advisor call log. Optional for compatibility: absent, the api’s configured environment resolves the call, as it did before this field. Named or not, the environment the call resolves in must be a project environment whose runs dispatch to the calling agent (setProjectEnvironmentAgent). This is postAdvise step 2, after enablement: a disabled organization’s call answers 200 no_answer with reason disabled at step 1, before this check. An enabled organization’s call that fails it answers 403 (code permission_denied) and sends nothing. An agent built on this contract sends it. Examples: development.
featurestringNoCalling feature; defaults server-side to “advisor”. Examples: advisor.
Calling feature; defaults server-side to “advisor”. Examples: advisor.
object_namestringNoThe schema object’s ODCS name (schema[].name) the advice is for. Optional.
The schema object’s ODCS name (schema[].name) the advice is for. Optional.
project_idstringNoThe control-plane project of the run that asks. Optional; with environment, source_slug and object_name it names the object on the call’s row in the advisor call log. When named, the environment the call resolves in must be an environment of this project whose runs dispatch to the calling agent (postAdvise step 2: 403 otherwise, once step 1 has found the advisor enabled).
The control-plane project of the run that asks. Optional; with environment, source_slug and object_name it names the object on the call’s row in the advisor call log. When named, the environment the call resolves in must be an environment of this project whose runs dispatch to the calling agent (postAdvise step 2: 403 otherwise, once step 1 has found the advisor enabled).
source_slugstringNoThe catalog source of the object the advice is for. Optional.
The catalog source of the object the advice is for. Optional.
toon_profilestringYesTOON profile of the source data; capped at 256 KB server-side.
TOON profile of the source data; capped at 256 KB server-side.

Advice  

type: Advice

The advisor’s response to POST /v1/advise. With outcome no_answer, pcf_yaml is empty, the token counts are 0 and cache_hit is false; provider and model name the own key’s provider and model with reason own_key_failed, what would have been asked with another reason, or are empty when nothing resolves. A cache hit is outcome answered, with cache_hit true and token counts 0 (postAdvise, step 4).

PropertyTypeRequiredDescription
cache_hitbooleanYesWhether the response was served from the advisor cache.
Whether the response was served from the advisor cache.
call_idstringNoThe call’s row in the advisor call log. Absent when no row is written: with reason disabled (see AdvisorCall for which calls are logged). Present on a cache hit. The agent passes it back as advisor_call_id when it files the classification, which sets the row’s result.
The call’s row in the advisor call log. Absent when no row is written: with reason disabled (see AdvisorCall for which calls are logged). Present on a cache hit. The agent passes it back as advisor_call_id when it files the classification, which sets the row’s result.
input_tokensintegerYesNumber of input tokens consumed.
Number of input tokens consumed.
modelstringYesLLM model that produced the advice. Examples: claude-sonnet-4-6.
LLM model that produced the advice. Examples: claude-sonnet-4-6.
no_answer_reasonAdvisorNoAnswerReasonNo
outcomeAdviseOutcomeYes
output_tokensintegerYesNumber of output tokens generated.
Number of output tokens generated.
pcf_yamlstringYesPCF (pipeline configuration format) YAML produced by the LLM.
PCF (pipeline configuration format) YAML produced by the LLM.
providerstringYesLLM provider that produced the advice. Examples: anthropic.
LLM provider that produced the advice. Examples: anthropic.

Advise Outcome  

type: AdviseOutcome

answered (a provider was asked and pcf_yaml holds its answer) or no_answer (no provider was asked, or the organization’s own key failed; no_answer_reason says which). An api older than this field omits it; a client reads an absent or empty outcome as answered.

Advisor Allowance Update  

type: AdvisorAllowanceUpdate

The payload for setOrgAdvisorAllowance.

PropertyTypeRequiredDescription
allowance_tokensintegerYesThe new allowance in tokens. 0 stops all metered calls. Examples: 1000000.
The new allowance in tokens. 0 stops all metered calls. Examples: 1000000.

Advisor Own Key Test  

type: AdvisorOwnKeyTest

The outcome of testAdvisorOwnKey.

PropertyTypeRequiredDescription
modelstringNoThe model tested; absent with reason not_set. Examples: claude-sonnet-5-5.
The model tested; absent with reason not_set. Examples: claude-sonnet-5-5.
okbooleanYesWhether the provider answered on the own key.
Whether the provider answered on the own key.
providerstringNoThe provider tested; absent with reason not_set. Examples: anthropic.
The provider tested; absent with reason not_set. Examples: anthropic.
reasonAdvisorOwnKeyTestFailureNo
tested_atstringYesWhen the test ran.
When the test ran.

Advisor Own Key Test Failure  

type: AdvisorOwnKeyTestFailure

Why a test of the own key failed; set exactly when ok is false. not_set: no own key is registered in the environment, so no provider was asked. invalid_key: the provider refused the key. quota_exceeded: the provider refused for the key’s quota or rate limit. provider_error: the provider answered with another error or could not be reached. timeout: the provider did not answer in time.

Advisor Own Key Registration  

type: AdvisorOwnKeyRegistration

The payload for setAdvisorOwnKey: the own key of one environment and the provider settings its calls use.

PropertyTypeRequiredDescription
api_keystringNoThe provider API key. Write-only: stored in the environment’s vault and never returned by any customer-facing or advisor operation. Required when the environment has no own key for this provider (400 otherwise); absent keeps that key. Outside this contract and unchanged by it, resolveSecret with the operator-bootstrap token is not limited to particular vault refs (it stays organization-wide, gated by the policy engine), so this key’s {environment}/llm/{provider} ref is within its reach. Likewise outside it, registerSecret and updateSecret with the operator-bootstrap token are organization-wide, so they can write a secret at that ref without setAdvisorOwnKey; this contract does not govern such a write.
The provider API key. Write-only: stored in the environment’s vault and never returned by any customer-facing or advisor operation. Required when the environment has no own key for this provider (400 otherwise); absent keeps that key. Outside this contract and unchanged by it, resolveSecret with the operator-bootstrap token is not limited to particular vault refs (it stays organization-wide, gated by the policy engine), so this key’s {environment}/llm/{provider} ref is within its reach. Likewise outside it, registerSecret and updateSecret with the operator-bootstrap token are organization-wide, so they can write a secret at that ref without setAdvisorOwnKey; this contract does not govern such a write.
base_urlstringNoOptional OpenAI-compatible gateway base URL (ADR-091). Only meaningful for provider gateway. A default gateway exists only where this deployment pins a gateway base URL: there an empty or absent value uses the pinned one, and the pinned one wins over the value saved here. A deployment that pins none refuses an empty or absent base_url for provider gateway with 400 (AdvisorProvider.requires_base_url). Examples: http://litellm:4000/v1.
Optional OpenAI-compatible gateway base URL (ADR-091). Only meaningful for provider gateway. A default gateway exists only where this deployment pins a gateway base URL: there an empty or absent value uses the pinned one, and the pinned one wins over the value saved here. A deployment that pins none refuses an empty or absent base_url for provider gateway with 400 (AdvisorProvider.requires_base_url). Examples: http://litellm:4000/v1.
modelstringYesLLM model; validated against the server-side allowlist for the provider. Examples: claude-sonnet-5-5.
LLM model; validated against the server-side allowlist for the provider. Examples: claude-sonnet-5-5.
providerstringYesLLM provider; validated against the server-side allowlist (e.g. anthropic, openai, gateway for an OpenAI-compatible gateway endpoint). The key is stored at {environment}/llm/{provider}. Examples: anthropic.
LLM provider; validated against the server-side allowlist (e.g. anthropic, openai, gateway for an OpenAI-compatible gateway endpoint). The key is stored at {environment}/llm/{provider}. Examples: anthropic.

Last updated on October 31, 2026