diff --git a/guides/webhooks.mdx b/guides/webhooks.mdx index 1d8267ea..5ad938f1 100644 --- a/guides/webhooks.mdx +++ b/guides/webhooks.mdx @@ -69,6 +69,10 @@ Below is an example of the JSON payload that will be sent: - `args` certain workflow steps can add data to the args field which is then made available to subsequent steps and to webhook payloads. - `faults` array of [fault](/api-ref/transform/jobs/fetch-a-job#response-faults) objects that represent errors that occurred during the processing of the job. + +These are the faults of the job identified by `transform_job_id`, and together with the same array on the [job itself](/api-ref/transform/jobs/fetch-a-job) they are the reliable record of what went wrong. Prefer them over the `faults` field on the [silo entry](/api-ref/silo/entries/fetch-an-entry), which exists for backwards compatibility and is only populated when the entry's last state came from a job that errored or failed. + + The webhook will expect a `200` or `204` response code. Any other response will be treated as an error and will be automatically retried after a delay. ## Retries diff --git a/workspace/white-label.mdx b/workspace/white-label.mdx index 2ff35be5..fc6eeb20 100644 --- a/workspace/white-label.mdx +++ b/workspace/white-label.mdx @@ -121,8 +121,16 @@ This workflow sends a webhook when the job completes, leaving the silo entry in - -Use the entry ID from the webhook to [fetch the entry](/api-ref/silo/entries/fetch-an-entry). It gives you the [state](/console/doc-states) to mirror in your UI, a `faults` array explaining anything that went wrong, and the attachments — typically the PDF and XML — to store or show to your user. + +Use the `silo_entry_id` from the webhook to [fetch the entry](/api-ref/silo/entries/fetch-an-entry). It gives you the [state](/console/doc-states) to mirror in your UI and the attachments — typically the PDF and XML — to store or show to your user. + +When something went wrong, read the errors from the **job**, not the entry: take the `transform_job_id` from the same webhook and [fetch the job](/api-ref/transform/jobs/fetch-a-job), then map its `faults` array onto your own error types. The webhook payload already carries that job's faults, so in many cases you can act on it without a second call. + + +Don't build fault handling on the `faults` field of the **silo entry**. A single entry can be processed by many jobs, and the entry only exposes faults as a backwards-compatible convenience: they are copied from the job that assigned the entry's most recent state, and only when that state is an error or failure. One job has exactly one set of faults, which makes the job the deterministic source. + +The exception is entries uploaded with `allow_invalid`, where the entry's faults describe why the stored document itself is invalid. + @@ -149,8 +157,8 @@ Invopop recalculates line sums, taxes and totals on upload, because each tax aut ## FAQs - -You can, but the silo entry is the better source of truth: it carries the document state, the faults array and the attachments in one response, which makes error handling and retries simpler. + +Both, for different things. The silo entry is the source of truth for the document itself — its current [state](/console/doc-states), its contents and its attachments — and it is what you mirror in your UI. The job is the source of truth for one execution of a workflow, so it is where you read `faults` from when a job errors or fails. Fetch the entry for the outcome, the job for the reason. No. Group workspaces by tax regime, not by customer. A single workspace holds as many registered suppliers as you need, and each invoice names the supplier it belongs to.