When to use this endpoint

Send the complete configuration from the Form mapping editor. This endpoint saves a mapping; preview must still validate a real Job’s answers before submission.

Authentication and permissions

Authenticate with signed API-key fields or a logged-in CRM session; session dispatch applies CSRF checks. The authenticated tenant must have features2.ukDigitalWasteManagement=1. The feature is read from the account record, not trusted from request input.

Requires Forms Edit through Core_requirePermission('edit', 'pageForms'), including this configuration read.

Parameters

ParameterTypeRequiredDescription
form_idInteger-compatibleYesExisting non-archived type-0 Job Form.
configNative object or JSON object textYesExplicit complete configuration, not a merge. Omission fails; an explicit empty object disables the integration and clears its selectors/field maps.
config.enabled, config.profile_id, config.profile_override_field_idTruthy value / stable IDsNoenabled uses PHP nonempty. A nonblank profile must be active; blank inherits the account default. A nonblank override must identify an existing main Select field.
config.fieldsObject keyed by provider pathNoAllowed main provider paths map to actual stable main meta.id values. Unknown paths and nonblank invalid IDs fail instead of being discarded. Blank/omitted map entries clear that mapping in the replacement.
config.waste_itemsObjectNotable_field_id identifies a main subform whose child is active. Mapped field IDs must exist in that child. Invalid tables/fields or nonempty waste mappings without a selected table fail.

Example request

$result = FM_api('DigitalWasteTracking_formConfigSave', [
	'form_id'=>'410',
	'config'=>'{"enabled": 1, "profile_id": "aaaaaaaaaaaaaaaa", "profile_override_field_id": "site-picker", "fields": {"carrier.organisationName": "carrier-name", "carrier.meansOfTransport": "transport"}, "waste_items": {"table_field_id": "waste-table", "fields": {"ewcCodes": "ewc", "wasteDescription": "description"}}}',
]);

Example response

{
  "ok": 1,
  "config": {
    "enabled": 1,
    "profile_id": "aaaaaaaaaaaaaaaa",
    "profile_override_field_id": "site-picker",
    "fields": {
      "carrier.organisationName": "carrier-name",
      "carrier.meansOfTransport": "transport"
    },
    "waste_items": {
      "table_field_id": "waste-table",
      "fields": {
        "ewcCodes": "ewc",
        "wasteDescription": "description"
      }
    }
  }
}

Errors and unusual responses

ResponseCondition
{"error":"not logged in"}No authenticated tenant context is available. Invalid signed credentials can be rejected by the dispatcher before the handler runs.
{"error":"UK Digital Waste Tracking is not enabled for this account"}The account feature is disabled.
{"error":"invalid configuration"}config is invalid JSON or not an array/object.
{"error":"invalid or archived receiving profile"}A nonblank profile_id is not active.
{"error":"invalid receiving profile override field"}The override ID is not a stable main-field ID.
{"error":"form edits are disabled for this account"}The shared Form edit lock applies.
{"error":"permission denied"}The required page action is absent; the shared permission helper retains its legacy roleless fallback.
{"error":"explicit configuration is required"}config is omitted.
{"error":"invalid waste table mapping"}The table is invalid/archived or field mappings have no table.

Legacy application errors may be returned with HTTP 200. Check the decoded response for error, not only the HTTP status.

Behaviour and edge cases

  • Mutations also honour features2.disableFormEdits through the shared Form helper; temporary Form-editor identities retain that helper’s exception. Reading configuration does not invoke this edit lock.
  • The full main-path allowlist is dateTimeReceived, carrier.organisationName, carrier.registrationNumber, carrier.reasonForNoRegistrationNumber, carrier.meansOfTransport, carrier.vehicleRegistration, carrier.address.fullAddress, carrier.address.postcode, carrier.emailAddress, carrier.phoneNumber, brokerOrDealer.organisationName, brokerOrDealer.registrationNumber, brokerOrDealer.address.fullAddress, brokerOrDealer.address.postcode, brokerOrDealer.emailAddress, brokerOrDealer.phoneNumber, hazardousWasteConsignmentCode, reasonForNoConsignmentCode, specialHandlingRequirements, yourUniqueReference, otherReferencesForMovement. Each value is a stable field ID, not a visible field name or position.
  • Replaces forms.meta.digital_waste_tracking while preserving other Form metadata and updates last_edited/cache/history. It does not rewrite completed Job answers, refresh select options or contact the provider.
  • The waste-path allowlist is ewcCodes, wasteDescription, physicalForm, typeOfContainers, numberOfContainers, weight.metric, weight.amount, weight.isEstimate, containsPops, pops.sourceOfComponents, pops.components, containsHazardous, hazardous.sourceOfComponents, hazardous.hazCodes, hazardous.components, disposalOrRecoveryCodes. IDs must belong to the selected active table.
  • Nonblank invalid main/waste IDs, unknown provider paths and an invalid table reject the whole replacement. A valid deliberately partial semantic map is allowed; required receipt coverage remains a readiness/preview concern. The profile override is required to be a Select.
  • Mutations use a checked tenant PDO transaction with the tenant-owner lock, preserving a caller’s savepoint. Writes and history commit together; a failed write/audit rolls back. A controlled save error asks callers to reload before retrying. No migration or deletion-lifecycle change is included.

Side effects

  • Atomically updates Form metadata/last_edited, cache invalidation and checked history. Provider submission and completed Job answers remain separate.

See it in Fieldmotion

CRM1

No direct CRM1 caller was found in the production JavaScript source. The operator workflow is implemented in CRM2.

CRM2

Forms > Job Form > Digital Waste Tracking > Save sends form_id plus config as JSON. It sends the whole mapping state, not a changed-field patch.

Related endpoints