How to Read a TaxOrch Tax Answer and Its Sources
Four fields decide what your interface is allowed to say, and one of them decides whether you may show a number at all. A short guide to reading a grounded answer before you build around it.
Most integrations get this wrong in the same way. They look for a figure, find one, and render it. The figure is usually right — and the times it is not are the times the contract was telling them something they were not reading.
Start with verification_status
Not the presence of a number. An abstention is a successful response with no
figure in it, and a client that keys off calculations being non-empty will
treat a refusal as a server error and retry it.
Then check what you are allowed to claim
Two fields decide the language your interface may use about the figure.
| Coverage status | May present as exact | What to say instead |
|---|---|---|
| covered | Yes | — |
| beta | Yes | Note that depth is limited |
| draft | No | Planning only. Never label it exact. |
| unavailable | No | There is no figure to present. |
The second is law_as_of. An answer shown without its law-as-of date has had
its most important caveat removed — the reader cannot tell whether they are
looking at this year's rules or last year's.
Handle the two outcomes that are not numbers
Render missing_facts as a form
Each entry carries a
promptwritten for a person and areasonexplaining why the question is being asked. Use both. A field labelled with the prompt and no reason looks arbitrary, and people abandon arbitrary forms.Render an abstention as a finding
It names the specific asset that is missing. Showing "something went wrong" throws that away and invites a retry that will fail identically.
Never invent a third path
No default branch that renders a number because the other cases did not match. That default is the single mistake this contract exists to prevent.
What never disappears
missing_facts, conflicts, assumptions and risks are present on every
high-risk answer and empty on a clean one. That is exactly why they get typed
as optional by mistake — the code compiles, ships, and then throws on the first
conflict in production.
// Wrong. Compiles today, breaks on the first interesting answer.
interface Answer {
conflicts?: Conflict[];
}
// Right. Present and empty, not absent.
interface Answer {
conflicts: Conflict[];
}If you take one thing from this: the fields describing what the system could not do are the ones that protect you, and they are the ones an interface tends to hide.
Where this fits
- Cases and workpapersWhere recordkeeping obligations is covered in depth