Replace the merchant-supplied configuration for a surface
The configuration is a string map by design: its shape is the surface’s own
business, declared by the descriptor’s config_schema, so typing it here
would put surface-specific knowledge into the generic layer. A surface that
declares a schema has the map validated against it (unknown keys and ill-typed
values are a 422); one that declares none accepts any map. Prerequisites are
re-evaluated against the new configuration before the response is returned.
/stores/{store_id}/surfaces/{surface_id}/configAuthorizationBearer token (JWT) · headerrequiredJWT issued by the external IdP via the OAuth 2.0 authorization-code flow (Kinde in
production; a simulator in test). The client obtains it and sends it as a Bearer token on
every authenticated call. Sarvex's services verify it — issuer, audience, signature
(IdP JWKS), expiry — and read identity and tenant from its claims. Sarvex does not issue
or revoke these tokens. merchant_id/store_id are read from the verified claims (and the
merchant→store mapping), never from the URL. The operator scope is required for
/operator/*. Operators acting on a specific merchant pass the X-Operate-As header,
which is recorded in the audit log.
store_idstringrequiredA store the caller's merchant owns. Authorized server-side against the principal; not a free-form tenant selector.
surface_idstringrequiredA surface id from the registry (GET /surfaces). Not a tenant selector — enrollment is always scoped to the caller's merchant server-side.
application/jsonconfigobjectEnrollment state after configuration.
surface_idstringrequiredstore_idstringrequiredstatesurface_staterequiredA store's enrollment position on one agent surface (internal/planes/control/surface). Per-store, per-surface, zero-to-many.
availableprerequisites_pendingconfiguredsubmittedverifyingenrolledsuspendedprerequisitesprerequisite_result[]requiredShow propertiesHide properties
prerequisite_resultcheck_idstringrequiredlabel_keystringrequiredpassedbooleanrequiredreasonstringMerchant-readable explanation of a failure. Empty on pass.
remediation_keystringvue-i18n key for the fix, where one applies.
remediation_urlstring<uri>evaluated_atstring<date-time>requiredartifactssurface_artifact[]requiredShow propertiesHide properties
surface_artifactartifact_idstringrequiredlabel_keystringrequiredurlstring<uri>detailobjectArtifact-specific read-only facts for display. Rendered generically as label/value rows.
generated_atstring<date-time>configobjectenrolled_atstring<date-time>last_verified_atstring<date-time>suspension_reasonstringupdated_atstring<date-time>requireddescriptorobjectrequiredEchoed alongside state so a client renders the whole enrollment flow from one response, with no per-surface knowledge of its own.
Show propertiesHide properties
surface_idstringrequireddisplay_name_keystringrequireddescription_keystringprotocolsurface_protocolrequiredThe wire protocol an agent surface speaks. Data on the descriptor, never a branch in code.
ucpacprequired_connectorsconnector_type[]required_capabilitiesstring[]Canonical UCP capability identifiers only. A free-form value is rejected at registry construction.
prerequisite_checksstring[]Named checks, in the order the merchant sees them. Each resolves to an adapter at registration.
artifactsstring[]Sarvex-generated, surface-scoped artifacts. Generated only for stores enrolling in this surface.
config_schemasurface_config_field[]The merchant-editable configuration this surface takes. The console renders a
form from it with no per-surface code. Empty means free-form (or no) config.
When non-empty, PUT .../config rejects unknown keys and ill-typed values
with a validation error.
Show propertiesHide properties
surface_config_fieldkeystringrequiredtypestringrequiredtext; bool ("true"/"false"); string_list (newline-separated); json
(a JSON document). Values are always strings on the wire.
textboolstring_listjsonlabel_keystringrequiredvue-i18n key.
help_keystringvue-i18n key for help text.
requiredbooleanrequiredAdvisory — a missing required value is a failing prerequisite, not a rejected request.
external_stepssurface_external_step[]Show propertiesHide properties
surface_external_stepstep_idstringrequiredlabel_keystringrequiredvue-i18n key. The descriptor owns identity, the console owns copy.
urlstring<uri>ownerstringrequiredWho the step waits on, so a client renders waiting states without surface-specific knowledge.
merchantsurfaceverification_signalstringNames what proves enrollment succeeded.
auto_enrollbooleanTrue for a surface that enrolls itself when the store reaches active.
direct_agent is the only such surface: it represents the plain fact that
any agent discovering the profile can transact, and exists so that "active
with no distribution partner" is explicit rather than implied.
blockedbooleanrequiredTrue when the store is not yet active — the one thing that holds enrollment at available.
blocked_reasonstringi18n key.
Resource not found within the caller's tenant.
errorobjectrequiredShow propertiesHide properties
codestringrequiredmessagestringrequireddetailsobject | nullStore is not UCP active.
errorobjectrequiredShow propertiesHide properties
codestringrequiredmessagestringrequireddetailsobject | nullRequest body failed validation.
errorobjectrequiredShow propertiesHide properties
codestringrequiredmessagestringrequireddetailsobject | null