ZAHLEN

Chapter 7

Retry Decision API


image

Single decisions, batch decisions, response interpretation, and confidence


Audience

Merchants | Developers | Integration Engineers


Commercial workflow

Payment Event -> Retry Decision -> Retry Outcome -> Investigation Run -> Reporting


Zahlen API User Guide v1.0

Source baseline: zahlen_deploy_0616A.tar.gz | June 2026

Chapter 7 - Retry Decision API


Learning objectives

By the end of this chapter, you should be able to choose the correct retry-decision contract, submit single and batch requests, interpret returned actions and explanations, and use confidence without

treating it as a guarantee.

The Retry Decision API evaluates payment evidence and returns an operational recommendation. It tells a merchant whether to retry now, wait for a scheduled retry day, stop retrying, or escalate for review. The API does not execute the payment and does not prove that a future retry will succeed.


Canonical retry schedule

Zahlen is built around the fixed retry schedule Day 1, Day 2, Day 6, and Day 16. A returned retry day must be interpreted within this schedule. Client code must not invent extra retry days or move

an authorization attempt outside the fixed sequence.


    1. Decision endpoints


      Method

      Path

      Contract

      Typical use

      POST

      /v1/retry-decision

      Legacy single decision

      Existing integrations requiring the full historical request and

      response structure.

      POST

      /v1/retry-decision/batch

      Legacy batch decision

      Evaluate up to 500 legacy-

      format events in one request.

      POST

      /v1/_next/retry-decision

      Next-generation single decision

      Streamlined decision contract for integrations selected during

      onboarding.


      Do not mix contracts

      The legacy and next-generation endpoints use different request and response models. Select one approved contract and map it explicitly. Do not send fields from one model to the other or build

      client logic that silently combines both.

    2. Authentication and idempotency

      Merchant-facing decision requests use the X-API-Key header. Tenant and merchant ownership are resolved from the authenticated key. Decision routes support Idempotency-Key where documented by the implementation; use one stable key for one logical decision operation.

      X-API-Key: zk_live_REPLACE_ME

      Idempotency-Key: order-8842-attempt-2 Content-Type: application/json


Why idempotency matters

    1. Legacy single decision

      POST /v1/retry-decision uses RetryDecisionRequest. Extra fields are forbidden. Five fields are required; the remaining fields provide issuer, processor, transaction, and policy context.

      Required request fields


      Field

      Type

      Purpose

      payment_token

      string

      Merchant-safe token representing the

      payment method.

      billing_cycle_id

      string

      Stable identifier for the subscription or

      billing cycle.

      event_ts_iso

      string

      Timestamp of the observed authorization

      or decline event.

      cycle_start_ts_iso

      string

      Start timestamp for the billing cycle.

      paymentech_code

      string

      Processor response or decline code

      expected by the legacy contract.


      Legacy request example


      curl -sS -X POST "$ZAHLEN_BASE_URL/v1/retry-decision" \

      -H "Content-Type: application/json" \

      -H "X-API-Key: $ZAHLEN_API_KEY" \

      -H "Idempotency-Key: cycle-2026-06-attempt-2" \

      -d '{

      "payment_token": "tok_001", "billing_cycle_id": "cycle_2026_06", "event_ts_iso": "2026-06-16T12:00:00Z", "cycle_start_ts_iso": "2026-06-01T00:00:00Z", "paymentech_code": "51",

      "card_network": "VISA", "amount": 29.99,

      "currency": "USD", "attempt_day_in_cycle": 2, "subscription_id": "sub_001"

      }'


Optional legacy fields include country and issuer context, BIN values, processor, recommended action evidence, outcome flags, order/invoice/subscription references, transaction kind, spike-alert controls, and deterministic or AI external-change mode. Send only fields your integration can populate accurately.

    1. Interpret the legacy response

      RetryDecisionResponse is organized into decision, reasoning, signals, explanations, metadata, and an optional policy block. This structure separates the control instruction from the evidence and version information used to produce it.

      Decision block


      Field

      Allowed values / type

      Interpretation

      action

      RETRY_NOW, WAIT, STOP, ESCALATE

      Primary operational instruction.

      state

      RETRY_SCHEDULED, RETRY_NOW_ELIGIBLE, DO_NOT_RETRY,

      REQUIRES_REVIEW

      More specific decision state.

      recommended_next_attempt_day_in_cycle

      integer or null

      Next permitted retry day when one is

      scheduled.

      recommended_next_attempt_at

      string or null

      Timestamp representation when provided.


      Reasoning and signals


      Section

      Important fields

      Use

      reasoning

      reason_code, reason, confidence,

      guidance_source

      Explain why the action was selected.

      signals

      seen_before, truth_confidence_band,

      external_status, analysis_mode

      Describe supporting evidence and prior

      observation.

      explanations

      array

      Present additional human-readable

      explanation when available.

      meta

      request_id, versions, processed_at,

      idempotency_key

      Support traceability and reproducibility.

      policy

      applied, merchant_id, rule_id, source

      Show whether a merchant policy affected

      the result.


      Action is the control signal

      Base automated workflow on the explicit action and state. Reason text is designed for explanation

      and support, not for fragile string matching.

    2. Legacy batch decision

      POST /v1/retry-decision/batch accepts BatchRetryDecisionRequest. The events array can contain up to 500 legacy decision requests. This is a schema ceiling, not a guaranteed throughput target.

      {

      "events": [

      {

      "payment_token": "tok_001", "billing_cycle_id": "cycle_2026_06_a", "event_ts_iso": "2026-06-16T12:00:00Z", "cycle_start_ts_iso": "2026-06-01T00:00:00Z", "paymentech_code": "51",

      "attempt_day_in_cycle": 1

      },

      {

      "payment_token": "tok_002", "billing_cycle_id": "cycle_2026_06_b", "event_ts_iso": "2026-06-16T12:01:00Z", "cycle_start_ts_iso": "2026-06-01T00:00:00Z", "paymentech_code": "91",

      "attempt_day_in_cycle": 2

      }

      ]

      }


Batch response


Field

Meaning

Client guidance

results

One evaluated item per returned decision

Correlate each result with the original event identity; do not rely only on array position

unless contractually guaranteed.

meta

Batch request/version metadata

Log request ID, processing time, and version

fields.

count

Number of returned results

Compare with the intended and submitted

event counts.


    1. Next-generation single decision

      POST /v1/_next/retry-decision uses NextRetryDecisionPayload. Only attempt_number is required, and it must be at least 1. The streamlined contract can carry decline, issuer, amount, timing, authorization, and recurring-payment context. Extra fields are forbidden.

      Core request fields


      Field

      Type

      Required

      Notes

      attempt_number

      integer

      Yes

      Minimum 1; identify the attempt

      within the merchant workflow.

      token

      string or null

      No

      Merchant-safe payment token.

      decline_code

      string or null

      No

      Observed decline or processor

      response code.

      issuer_bin

      string or null

      No

      Issuer identification context;

      never send a full PAN.

      issuer_name / issuer_country /

      card_brand

      string or null

      No

      Issuer and card context.

      amount_minor

      integer or null

      No

      Nonnegative integer in minor

      currency units.

      currency

      string or null

      No

      Currency code paired with

      amount_minor.

      decline_category

      string or null

      No

      Merchant or processor

      classification when available.

      event_timestamp

      string or null

      No

      Observed event time.

      authorization_id /

      authorization_latency_ms

      string / number or null

      No

      Processor correlation and latency.

      merchant_category_code /

      recurring_indicator / transaction_initiator

      string or null

      No

      Transaction context.


      Request example


      curl -sS -X POST "$ZAHLEN_BASE_URL/v1/_next/retry-decision" \

      -H "Content-Type: application/json" \

      -H "X-API-Key: $ZAHLEN_API_KEY" \

      -H "Idempotency-Key: order-8842-attempt-2" \

      -d '{

      "token": "tok_001", "attempt_number": 2,

      "decline_code": "51",

      "issuer_bin": "411111", "card_brand": "VISA", "amount_minor": 2999, "currency": "USD",

      "event_timestamp": "2026-06-16T12:00:00Z"

      }'

    1. Interpret the next-generation response

      NextRetryDecisionResponse provides a flat decision envelope with traceability, explanation, policy, and issuer context. Nullable fields must be represented explicitly in typed clients.


      Field

      Type

      Interpretation

      request_id

      string

      Request correlation for logs and support.

      decision_id

      string

      Durable identifier for this decision.

      merchant_id

      string

      Resolved merchant context.

      token

      string or null

      Returned merchant token correlation.

      attempt_number

      integer

      Attempt evaluated.

      decision

      string

      Primary decision value; use as the control

      signal.

      retry_day

      integer or null

      Scheduled retry day, when applicable.

      reason_code

      string

      Machine-readable explanation category.

      reason_detail

      string or null

      Human-readable explanation.

      policy_source / matched_policy_id

      string or null

      Policy provenance.

      confidence

      number or null

      Evidence-strength score, not a guarantee.

      created_at

      string

      Decision creation timestamp.

      idempotent_replay

      boolean

      Whether the result was served as an

      idempotent replay.

      issuer_context

      object or null

      Extensible issuer evidence.

      explainability_sections

      array

      Additional structured explanations.

      decision_trace

      object

      Machine-readable trace details.


      Nullable retry day

      A null retry_day can be correct. It may accompany a stop, escalation, or other decision that

      intentionally does not schedule another payment attempt. Do not substitute the next calendar day.


      Schedule validation

      When a retry is authorized, client validation should confirm that the returned retry day is one of the canonical schedule points: 1, 2, 6, or 16. An unexpected value should be logged and escalated rather than silently executed.

      ALLOWED_RETRY_DAYS = {1, 2, 6, 16}

      if response["retry_day"] is not None:

      if response["retry_day"] not in ALLOWED_RETRY_DAYS:

      raise ValueError("Unexpected retry day; do not execute payment")

    1. Confidence scores

      Confidence describes the strength and consistency of the evidence behind a decision. It does not measure the dollar importance of the account and does not promise authorization success. The legacy response uses LOW, MED, or HIGH; the next-generation response exposes a nullable numeric confidence value.


      Confidence concept

      Correct interpretation

      Incorrect interpretation

      LOW / lower numeric confidence

      Limited, sparse, new, or conflicting evidence; preserve decision but increase

      review and monitoring.

      The decision is automatically wrong.

      MED / middle-range confidence

      Useful evidence with some uncertainty;

      follow the decision and retain explanation.

      There is a fixed universal success

      percentage.

      HIGH / higher numeric confidence

      Strong, consistent evidence for the selected

      action.

      The payment is guaranteed to recover.


      Operational use

      • Always honor the explicit decision before interpreting confidence.

      • Expose reason and confidence to operators who investigate exceptions.

      • Use confidence to select review, monitoring, or escalation intensity.

      • Do not create undocumented confidence thresholds unless they are part of an approved merchant policy.

      • Record confidence with the decision ID, request ID, rules or policy source, and timestamp.


        High confidence does not replace outcome reporting

        A high-confidence retry recommendation still requires a real processor attempt and a reported

        retry outcome. Decision quality is learned and measured only when the merchant closes the loop.

    2. Decision-handling workflow

      1. Build a schema-valid request using the approved legacy or next-generation contract.

      2. Send X-API-Key and a stable Idempotency-Key for the logical operation.

      3. Persist the complete response before scheduling or executing a payment action.

      4. Read the explicit decision or action and state.

      5. Validate any retry day against Day 1, Day 2, Day 6, and Day 16.

      6. Use reason, confidence, policy, and issuer context for explanation and review.

      7. Execute the permitted payment attempt in the merchant payment stack.

      8. Report the observed result through POST /v1/retry-outcome.

      Example control logic


      decision = response["decision"]

      retry_day = response.get("retry_day")

      if decision in {"STOP", "DO_NOT_RETRY"}: cancel_future_payment_attempts()

      elif decision in {"ESCALATE", "REQUIRES_REVIEW"}: open_manual_review(response)

      elif retry_day in {1, 2, 6, 16}: schedule_payment_attempt(day=retry_day)

      else:

      hold_and_alert("Decision cannot be safely executed")


Recommendation is not settlement

The Retry Decision API recommends operational behavior. The processor result and settlement

status remain separate facts and must be reported through the outcome workflow.

    1. Error handling and safe retries


      Status

      Meaning

      Client response

      400

      Malformed or business-invalid request

      Correct the request; do not blindly retry.

      401

      Missing or invalid API key

      Check secret injection, key status, and

      environment.

      403

      Authenticated but not authorized

      Check plan, endpoint access, or contract.

      409

      Conflict or idempotency mismatch

      Compare the original body and

      idempotency key.

      422

      Schema validation failed

      Fix required, typed, constrained, or

      unknown fields.

      429

      Rate or quota enforcement

      Honor Retry-After when present and use

      backoff with jitter.

      500/503

      Server or dependency failure

      Retry with the same idempotency key and

      bounded backoff.


      Production checklist

      • The client implements exactly one approved decision contract per integration path.

      • Unknown request fields are rejected locally before transmission.

      • API keys and idempotency keys are centralized and never logged as secrets.

      • Every response is logged using request_id and decision_id.

      • Nullable retry day, confidence, policy, and issuer context are handled safely.

      • Only Day 1, Day 2, Day 6, and Day 16 can create payment attempts.

      • Batch reconciliation does not rely on fragile assumptions.

      • 429 and transient 5xx retries are bounded, jittered, and idempotent.

      • Every executed recommendation is followed by outcome reporting.


Chapter summary

The Retry Decision API converts payment evidence into an explainable action. Reliable integrations keep legacy and next-generation contracts separate, use idempotency for safe HTTP retries, treat confidence as evidence strength, obey the fixed Day 1/2/6/16 schedule, and report the actual

outcome.