Digital Waste Tracking
Submit or update a waste receipt
/a/DigitalWasteTracking_submit
Send the current saved completed Job to the receiving environment and retain an ambiguity-safe receipt mapping.
When to use this endpoint
Save Job answers, inspect status and preview, then explicitly submit. For uncertain outcomes, reconcile externally before retrying; a timeout does not prove the provider rejected a receipt.
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 Jobs Edit through Core_requirePermission('edit', 'pageJobs').
Job reads and mutations enforce the authenticated tenant, active Job, TeamAccess department/assignment scope and the legacy department-based customer boundary. Collections filter before counts/pagination; explicit Job and cancellation requests check access before a service call or queue mutation.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
job_id | Integer-compatible | Yes | Nonzero existing non-deleted configured Job. Complete (1) or Processed (2) is required for new sends/updates. |
allow_update | Truthy/falsey value | No | Default false. An accepted mapping otherwise returns already_submitted; nonempty allows PUT using its tracking ID. String "false" is truthy. |
expected_hash | String | Recommended | The 64-character lowercase hexadecimal preview request_hash. CRM2 sends it for confirmation/update; mismatch stops the provider write. Legacy omission remains accepted, and an already-submitted no-send result retains its idempotent behavior. |
Example request
$result = FM_api('DigitalWasteTracking_submit', [
'job_id'=>'1042',
'allow_update'=>'0',
]);
Example response
{
"ok": 1,
"tracking_id": "WT-SYNTHETIC-1042",
"updated": false,
"warnings": [],
"service_charge_expires_at": null,
"request_hash": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
"profile_id": "aaaaaaaaaaaaaaaa"
}
A known provider success may include submitted=1 and/or warning when history/payment follow-up fails. Inspect the saved receipt; do not send another receipt to repair local history.
Errors and unusual responses
| Response | Condition |
|---|---|
{"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":"job_not_complete"} | The current saved Job is neither Complete nor Processed. |
{"error":"validation_failed"} | Local receipt validation failed; categories accompanies the error. |
{"error":"ambiguous_previous_submission"} | A previous outcome remains uncertain. |
{"error":"submission_busy"} | The service’s local Job lock is held. |
{"error":"ambiguous_provider_response"} | The provider may have accepted the write; inspect/reconcile rather than resubmit. |
{"error":"provider_payment_required"} | The provider returned HTTP 402. |
{"error":"provider_rate_limited"} | The provider returned HTTP 429; retryable/retry_after may be included. |
{"error":"request_hash_changed"} | The saved Job/payload changed during pre-send validation. |
{"error":"permission denied"} | The required page action is absent; the shared permission helper retains its legacy roleless fallback. |
{"error":"job not found or outside your record scope"} | The explicit Job or queue’s Job is missing, deleted or hidden by record scope. Bulk queueing reports this per Job. |
Legacy application errors may be returned with HTTP 200. Check the decoded response for error, not only the HTTP status.
Behaviour and edge cases
- The CRM forwards this operation to its signed on-complete service with the tenant and actor installed server-side. A caller cannot choose another tenant. Missing service configuration returns
Digital Waste Tracking service is not configured; a non-JSON service reply returnsDigital Waste Tracking service returned an invalid response. - Builds from saved Job main/table answers using stable mapped field IDs and their current names. It does not accept a caller-supplied provider payload. Receiving profile precedence is Job override, Form selection, account default; a recorded submission/ambiguity pins the historical profile and can include an archived profile.
- Receipt time uses the mapped answer or falls back to date_completed. Naive dates use the tenant timezone setting, default Europe/London, and serialize with an explicit offset. Booleans recognize 1/yes/true/on; code lists split on commas/newlines; numberOfContainers must be whole, and weight amount must be finite and positive.
- A previous nonambiguous mapping with allow_update=false returns {ok:1,already_submitted:1,tracking_id:...} before rebuilding/revalidating current data. Ambiguous mappings always fail with ambiguous_previous_submission until reconciliation.
- New sends require local structural validation and, when fresh, reference validation. A validation_failed error includes categories. A failed reference fetch without a usable cache blocks sending; usable stale references permit provider-side validation. Ordinary manual calls do not automatically queue retryable failures.
- Before sending, a local per-Job file lock and a tenant Job-row transaction compare saved answers/completion/current mapping and rebuild the hash. The service commits an ambiguous:
marker before the provider write, so other replicas see a durable uncertain state. Changed data/state stops the send. - Provider POST requires HTTP 201 and a nonblank returned tracking ID; updates use PUT and require HTTP 200. A transport timeout, missing tracking ID, status below 100 or HTTP 5xx is ambiguous. HTTP 429 is retryable with bounded retry_after; HTTP 402 reports payment required; other unexpected responses expose sanitized provider categories/fields.
- Successful receipts retain profile identity, tracking ID and mapping time, log submitted/updated and store last service-charge state. Unknown warnings are sanitized; missing disposal/recovery codes normalize to DisposalOrRecoveryCodesNotProvided. A provider success can still include warnings.
- An explicit update uses the originally recorded profile even after archive or Form selection changes. It does not create a new receiving-environment identity. The server does not assert valid government approval or verify a permit beyond implemented syntax checks.
- Marker inserts/updates, final mapping changes and reconciliation writes now check persistence acknowledgements. A failed marker prevents provider dispatch. Failed finalization after provider dispatch preserves ambiguity; follow-up history/payment/notice failure retains the known outcome and returns warning text rather than inviting replay.
- The pre-dispatch marker transaction also locks the tenant owner before rebuilding the current payload, coordinating receiving-profile changes with receipt history. No database transaction is held over provider HTTP.
Side effects
- Makes provider OAuth/reference and POST/PUT requests. Writes durable receipt/ambiguity mappings, Job DWT logs, cached profile payment/expiry state and deduplicated notices to active configured recipients. Does not alter Job answers/completion.
See it in Fieldmotion
CRM1
No direct CRM1 caller was found in the production JavaScript source. The operator workflow is implemented in CRM2.
CRM2
On a configured Job Form confirm the preview. CRM2 calls DigitalWasteTracking_submit with allow_update=0 for a new receipt and 1 for an explicit update. Operations > Update receipt also sends allow_update=1.
Related endpoints
DigitalWasteTracking_preview— Inspect current saved data and categories first.DigitalWasteTracking_queue— Queue validated new receipts in bulk.DigitalWasteTracking_reconcile— Resolve a durable ambiguous outcome before retrying.DigitalWasteTracking_status— Reload the retained local mapping.