Turn computed, decline, review, and error responses into safe product behavior without private explanation.
Developers and product managers wiring response envelopes into workflow state.
Use GET /api/mcp/tax-capabilities before sending taxpayer-like payloads. Only modeled fields and required affirmations can compute.
Reference links: GET /api/mcp/tax-capabilities for the supported envelope, OpenAPI for request and response schema, roadmap feedback, changelog/release notes, support/contact, and terms.
Start with computed, status, billed, retry_safe, and next_action before reading any tax line.
A deterministic decline is a successful safety outcome. It is not an outage and should not trigger blind retries.
Provenance appears on successful computed or workflow responses; decline responses use code and reason instead.
Computed responses may show tax figures with derivation and legal_notice.
Decline and needs_review responses should show the reason, next_action, and review routing. Do not invent a fallback tax estimate.
| State | HTTP | Billed | Retry safe | next_action | Client display guidance |
|---|---|---|---|---|---|
| Computed | 200 | Yes on metered customer plans | true with the same Idempotency-Key | none | Show computed figures with derivation and provenance. |
| Deterministic decline | 200 | Yes on metered customer plans | false for the same unsupported body | review_inputs | Show the reason and route to review; do not show a tax estimate. |
| needs_review | 200 | Yes on metered customer plans | true for replay; human review is still required | review_inputs | Show the review queue item, diff, reason, and provenance. |
| Validation error | 400 | No | false until request shape is fixed | fix_request_and_resubmit | Show a request-error state and tell the developer what field to fix. |
| Auth error | 401/403 | No | false until credentials are fixed | check_credentials | Ask the operator to check, rotate, or unsuspend the API key. |
| Quota or rate limit | 429 | No | quota: false; rate: true after backoff | upgrade_plan_or_wait_next_period or retry_after_backoff | Hard-stop quota or transient rate-limit message; do not overrun. |
| Idempotency replay | 200 | Once total | already replayed | none | Show the original result and reassure that replay did not double bill. |
| Idempotency mismatch | 409 | No | false with that key | use_new_idempotency_key | Client bug: same key was used for a different body. |
| Idempotency in progress | 409 | No | true with the same key after a short wait | retry_after_inflight_completes | Show in-progress and retry the same key. |
| Server failure | 500/503 | No | 500: false; 503: true after backoff | fix_request_and_resubmit or retry_after_backoff | Open support if persistent; do not show a computed result. |
First evaluators should be able to explain these states without private help before sending taxpayer-like payloads. Each row names the guide to read, the safe recovery behavior, and the privacy-safe telemetry event that can detect confusion.
| State to understand | Expected understanding | Primary guide | Safe recovery | Telemetry hook |
|---|---|---|---|---|
| Computed 200 | A computed 200 can show figures, provenance, legal_notice, billed, retry_safe, and next_action. | read-response | Replay the same Idempotency-Key for network uncertainty; do not change the body under the same key. | docs_guides_computed_comprehension |
| Deterministic decline 200 | A computed:false 200 is a successful safety answer, not an outage or a free retry loop. | deterministic-decline-ui | Show code, reason, billed, retry_safe, and next_action; route to review or feedback without a tax estimate. | docs_guides_decline_comprehension |
| needs_review 200 | needs_review is not a final computed tax answer; it is a human-review workflow state. | read-response | Show diff, reason/provenance, billed, retry_safe, and next_action; route to a review queue. | docs_guides_needs_review_comprehension |
| Validation error | A 400 validation failure is unbilled and should be fixed before resubmitting. | billing-retries-quota | Fix the request shape; do not ask support to infer a missing taxpayer fact. | docs_guides_validation_recovery_view |
| Auth error | A 401/403 auth failure is unbilled and usually means the API key or account state needs attention. | billing-retries-quota | Check, rotate, or unsuspend the key; never paste keys or bearer tokens into support or feedback. | docs_guides_auth_recovery_view |
| Quota or rate limit | A 429 is unbilled; monthly quota is a hard cap, while per-minute rate limit can wait/back off. | billing-retries-quota | Wait, back off, or use account/billing support; do not expect silent overage. | docs_guides_quota_recovery_view |
| Idempotency replay | Same-key same-body replay returns the stored result and bills once total. | billing-retries-quota | Reuse the same key for uncertainty about the same logical POST. | docs_guides_replay_comprehension |
| Idempotency mismatch | Same-key different-body mismatch is a client bug, unbilled, and must not be retried with that key. | billing-retries-quota | Use a new key only for a new logical request after fixing the client bug. | docs_guides_mismatch_recovery_view |
| Idempotency in progress | An in-progress response is unbilled at failure time and may be retried with the same key after a short wait. | billing-retries-quota | Retry the same key after the in-flight request settles. | docs_guides_in_progress_recovery_view |
| Server failure | A 500/503 is unbilled and must not produce a guessed tax result in the client UI. | read-response | Retry only when the response class says retry is safe; open support if persistent. | docs_guides_server_failure_recovery_view |
Preflight this example against the capability manifest before sending taxpayer-like payloads. It names modeled fields, required affirmations, deterministic decline codes, needs_review states, not-modeled residuals, billing semantics, and docs links. OpenAPI lives at /api/openapi.json.
{
"computed": true,
"year": 2025,
"filingStatus": "single",
"taxableIncome": 69250,
"incomeTax": 10149,
"totalTax": 10149,
"billed": true,
"retry_safe": true,
"next_action": "none",
"provenance": {
"engine": "deterministic",
"jurisdiction": "federal",
"tax_year": 2025
},
"legal_notice": {
"ref": "https://tax-mcp.com/terms#compute-notice",
"version": "v1"
}
}Preflight this example against the capability manifest before sending taxpayer-like payloads. It names modeled fields, required affirmations, deterministic decline codes, needs_review states, not-modeled residuals, billing semantics, and docs links. OpenAPI lives at /api/openapi.json.
{
"computed": false,
"code": "schedule_c_needs_review",
"reason": "Schedule C self-employment compute requires scheduleCIsSingleSolePropFinalNetAffirmed:true before Tax MCP can compute this bounded path.",
"billed": true,
"retry_safe": false,
"next_action": "review_inputs"
}Preflight this example against the capability manifest before sending taxpayer-like payloads. It names modeled fields, required affirmations, deterministic decline codes, needs_review states, not-modeled residuals, billing semantics, and docs links. OpenAPI lives at /api/openapi.json.
{
"status": "needs_review",
"computed": {
"computed": true,
"state": "ca",
"year": 2025,
"stateTaxableIncome": "<computed value elided>",
"totalTax": "<computed value elided>"
},
"diff": [
{
"line": "CA AGI (540:17)",
"engine": "<computed value elided>",
"filed": "<filed value supplied by caller, elided>",
"delta": "<difference elided>",
"cls": "DIFFERS",
"note": "source set appears incomplete vs the filed oracle; a human reviews"
}
],
"billed": true,
"retry_safe": true,
"next_action": "review_inputs",
"provenance": {
"engine": "deterministic",
"jurisdiction": "ca",
"tax_year": 2025
}
}{
"error": "invalid_request",
"billed": false,
"retry_safe": false,
"next_action": "fix_request_and_resubmit",
"reason": "Correct the request body before resubmitting."
}Privacy-safe guide telemetry may record only named events and coarse categories. It must never include API keys, bearer tokens, taxpayer documents, raw taxpayer PII, full unredacted request/response bodies, or unredacted support text.
| Event | Surface | Purpose | Safe fields |
|---|---|---|---|
docs_guide_index_view | /docs/guides | Detect whether evaluators reach the guide index from docs or quickstart. | session_id, surface, timestamp |
docs_guides_comprehension_map_view | /docs/guides | Detect whether first users see the response-class comprehension map before sending payloads. | session_id, surface, timestamp |
docs_guides_to_quickstart_click | /docs/guides/* | Measure guide-to-first-call continuity without recording request bodies or secrets. | session_id, guide_slug, timestamp |
docs_guides_support_click | /docs/guides/* | Route account or operational confusion to support without collecting raw support text. | session_id, guide_slug, support_category, timestamp |
docs_guides_feedback_click | /docs/guides/* | Route unsupported-envelope surprises to structured feedback without taxpayer PII. | session_id, guide_slug, response_class, decline_or_error_code, timestamp |
docs_guides_privacy_notice_view | /docs/guides/* | Confirm the no-secrets/no-PII support boundary is visible before support or feedback handoff. | session_id, guide_slug, timestamp |
Forbidden fields: api_key, bearer_token, raw_taxpayer_document, raw_taxpayer_pii, full_unredacted_request_body, full_unredacted_response_body, unredacted_free_form_support_text.