Forms built in the backend form editor use generated element identifiers
(text-1, multicheckbox-2, ...) that carry no meaning and cannot be renamed
without breaking the other finishers configured on the form. ApplicationApiFinisher
therefore sends two halves: a small mapped core (firstName, lastName, email, ...)
that a developer configures per form and MyEP can rely on, plus every remaining
submitted value keyed by the element label for a human to read.
Each submission also carries where it came from: the form identifier and its
editor-given name, plus the uid and canonical URL of the page it was submitted
from - the same definition is embedded on several pages, so the page is what
distinguishes them. The URL is generated through the site router in the visitor's
language, like AddReferrerFinisher does it.
Labels come from the form definition rather than TranslationService, so the keys
do not shift with the site language. Values are normalized for JSON: dates to
Y-m-d, uploads to the file name, multi-value elements to a list, empty values
dropped, unsupported objects skipped with a log warning.
Like BpnApiFinisher the request failure is only logged, so a MyEP outage never
costs the application mail.
The endpoint (POST applications) does not exist in MyEP yet; the contract handed
over to that team lives in .ddev/plans/MYEP-APPLICATION-ENDPOINT.md. Until it is
built the finisher is registered but attached to no form.
Co-Authored-By: Claude Opus 5 <[email protected]>