---
title: "Update an existing app"
method: PATCH
path: "/v1/app-config/{appId}/{userId}"
tags: ["appConfig"]
---

# Update an existing app

`PATCH /v1/app-config/{appId}/{userId}`

## Path parameters

- `appId` string, required
- `userId` string, required

## Request body

- UpdateAppConfig
  - `fieldMappers` FieldMapper[] — list of default field mappers
    - `id` string — unique id
    - `key` string — stable semantic key used by per-install AppConfig overrides/disables. Defaults to the single charthop field; an explicit key is required for multi-output mappers.
    - `readOnly` boolean — when true, this mapper only DEFINES how to read the value from the source system (for the outbound diff to compare against); it is not synced into ChartHop, so its charthopFields key is just a correlation handle and need not be a real ChartHop field.
    - `charthopFields` string[], required — list of ChartHop fields
    - `remoteFields` string[], required — list of remote fields
    - `type` string, required — type of field mapper to apply for mapping remote fields to ChartHop fields
    - `defaultCharthopValue` string — default charthop value
    - `defaultRemoteValue` string — default remote value
    - `defaultAmount` number — default amount
    - `defaultCurrency` string — default currency
    - `transformFunction` string — transform function
    - `charthopToRemoteTransformFunction` string — charthop to remote transform function
    - `map` object — map
    - `charthopToRemoteMap` object — charthop to remote map
    - `idField` string — id field
    - `nameField` string — name field
    - `remoteToCharthopMultiplier` number — remote to Charthop Multiplier
    - `separator` string — separator for join field mapper
    - `expression` string — CQL expression for the 'expression' field mapper. The single remote field's value is bound to `value`; each remote field is also addressable by its own name. e.g. split(value, "/")[2]
  - `customFieldMappers` FieldMapper[] — list of custom field mappers by a user
    - `id` string — unique id
    - `key` string — stable semantic key used by per-install AppConfig overrides/disables. Defaults to the single charthop field; an explicit key is required for multi-output mappers.
    - `readOnly` boolean — when true, this mapper only DEFINES how to read the value from the source system (for the outbound diff to compare against); it is not synced into ChartHop, so its charthopFields key is just a correlation handle and need not be a real ChartHop field.
    - `charthopFields` string[], required — list of ChartHop fields
    - `remoteFields` string[], required — list of remote fields
    - `type` string, required — type of field mapper to apply for mapping remote fields to ChartHop fields
    - `defaultCharthopValue` string — default charthop value
    - `defaultRemoteValue` string — default remote value
    - `defaultAmount` number — default amount
    - `defaultCurrency` string — default currency
    - `transformFunction` string — transform function
    - `charthopToRemoteTransformFunction` string — charthop to remote transform function
    - `map` object — map
    - `charthopToRemoteMap` object — charthop to remote map
    - `idField` string — id field
    - `nameField` string — name field
    - `remoteToCharthopMultiplier` number — remote to Charthop Multiplier
    - `separator` string — separator for join field mapper
    - `expression` string — CQL expression for the 'expression' field mapper. The single remote field's value is bound to `value`; each remote field is also addressable by its own name. e.g. split(value, "/")[2]
  - `customOutboundFieldMappers` AdpOutboundFieldMapper[] — list of custom outbound field mappers
    - `id` string, required
    - `description` string, required
    - `namespace` string, required
    - `valueMappers` OutboundValueMapper[], required
      - `id` string, required
      - `charthopSide` object, required
      - `externalSide` string, required
      - `options` object
      - `charthopToExternalTransform` string
    - `options` object
    - `gate` string
  - `disabledFieldMappers` string[] — list of disabled inbound field mappers by id
  - `enabledOutboundFieldMappers` string[] — list of enabled outbound field mappers by id
  - `templateMatchers` object[] — template field matchers defined by a user
  - `options` object — app specific options
  - `outboundFieldMappers` OutboundFieldMapper[] — per-install custom config-driven outbound field mappers
    - `charthopExprs` string[], required — ordered CQL expressions evaluated against the ChartHop entity; one resolves to a scalar, two or more to a list passed to the transform (e.g. a money range).
    - `key` string — stable semantic name for this value: the op-call references it as {{key}}, the diff joins it to the inbound read of the same key, and per-install AppConfig overrides/disables key off it. Defaults to the single charthopExpr; required when charthopExprs has multiple entries or the expression is a formula.
    - `writeAs` string — remote write path for a value routed through a generic collector (e.g. "custom_fields.employment_type"); omitted for fields the op-call params name directly. Dotted paths nest into the request body.
    - `transform` string — optional named transform applied to the value before it is bound
    - `transformArgs` object — optional static configuration passed to the transform (e.g. codelist domain/name)
    - `charthopFilter` string — optional CQL boolean; when it resolves to false the mapper is skipped
    - `ifOption` string — optional install-option name; the mapper applies only when that boolean option is set, or only when it is not if the name is prefixed with "!". Unlike charthopFilter (a per-record CQL boolean) this is fixed for the whole install, so two mappers sharing a key with opposing conditions express "this field is sourced differently when the option is on".
    - `refEntity` string — optional entities-catalog type (e.g. "department", "office", "user") to match the value against -> remote id(s); absent passes the value through. Cardinality follows the body property's type.
    - `clearWhenEmpty` boolean — whether an empty ChartHop value clears the remote field on an update, overriding the sync family's default. Set false for a field whose blank means "unknown" rather than "none", so a gap in ChartHop can't erase a good remote value; set true for a reference (e.g. manager) whose absence genuinely means there is none. A reference the ChartHop side HAS but the remote couldn't match is never cleared either way — that is a matching failure, not an empty field, and it is logged as one.
    - `writeTo` string — which remote record receives this value: the job (absent, the default) or the opening namespace (AtsAppConfig.openingConfig.namespace, "opening") for a vendor whose openings hold their own field values. An opening-targeted mapper is written by openingConfig.updateFields, not the job write.
  - `disabledOutboundFieldMapperKeys` string[] — keys (mapper.key ?: charthopExpr) of shipped config-driven outbound field mappers disabled per install
  - `outboundGroupMemberships` OutboundGroupMembership[] — group rules for a config-driven identity sync
    - `remoteGroupName` string, required — remote group name, matched against the group entity's nameField
    - `charthopFilter` string, required — CQL boolean evaluated per person; true means the person belongs to this group
    - `remoteGroupId` string — optional remote group id, matched before the name when set

## Response `204`

app config updated

## Other responses

- `400` — invalid data
- `401` — not authorized
- `403` — permission denied
- `404` — not found
- `409` — duplicate outbound field mapper or value mapper id

---

[API](https://skmtc.net/charthop/apis/charthop-api.md) · [All operations](https://skmtc.net/charthop/apis/charthop-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/charthop/charthop-api/revisions/2de21f45f447/schema)
