> ## Documentation Index
> Fetch the complete documentation index at: https://docs.varmo.fi/llms.txt
> Use this file to discover all available pages before exploring further.

# Track card delivery status with Varmo

> Poll the Varmo Status API to surface real-time card delivery progress to cardholders, from dispatch through to arrival at their door.

This guide walks you through polling the Varmo Status API so that your application can show cardholders a live view of where their card is in the delivery journey — from the moment it leaves the issuer's fulfillment center to the day it arrives.

## Prerequisites

<Note>
  Before you begin, make sure you have:

  * A valid Varmo API key with read access to the Status API
  * A dispatch `id` (UUID) generated by your card issuing system at the point of card dispatch
</Note>

<Steps>
  <Step title="Store the dispatch ID">
    When your card issuing system dispatches a physical card, it generates a UUID that uniquely identifies that dispatch event. Store this UUID in your database alongside the cardholder's record — it is the `{id}` path parameter for every Varmo Status API call you make for this card.

    ```json dispatch record example theme={null}
    {
      "cardholder_id": "usr_9f3c2a",
      "dispatch_id": "12b986fd-8f73-4a55-b1b1-1b3f203c7522",
      "dispatched_at": "2026-04-29T14:22:01Z"
    }
    ```

    If your issuing platform does not expose a dispatch UUID directly, generate one at the time of dispatch and store it before calling any downstream fulfillment service.
  </Step>

  <Step title="Poll for status">
    Call `GET https://api.varmo.fi/v1/status/{id}` with your dispatch UUID and a Bearer token in the `Authorization` header.

    <CodeGroup>
      ```bash cURL theme={null}
      curl --request GET \
        --url https://api.varmo.fi/v1/status/12b986fd-8f73-4a55-b1b1-1b3f203c7522 \
        --header "Authorization: Bearer YOUR_API_KEY"
      ```

      ```python Python theme={null}
      import requests

      dispatch_id = "12b986fd-8f73-4a55-b1b1-1b3f203c7522"
      api_key = "YOUR_API_KEY"

      response = requests.get(
          f"https://api.varmo.fi/v1/status/{dispatch_id}",
          headers={"Authorization": f"Bearer {api_key}"},
      )
      response.raise_for_status()
      data = response.json()
      ```
    </CodeGroup>

    Poll every 12–24 hours after dispatch. As the current date approaches `prediction.delivery_window.max`, increase polling frequency to every 2–4 hours so that your UI reflects the latest prediction before the card arrives.
  </Step>

  <Step title="Parse the status">
    Read `status`, `prediction.delivery_window`, and `prediction.confidence_level` from the response to determine what to show the cardholder.

    ```javascript parse-status.js theme={null}
    function parseDeliveryStatus(response) {
      const { status, prediction, ui_suggestion } = response;

      const deliveryWindow = prediction.delivery_window;
      const confidence = prediction.confidence_level;

      const windowStart = new Date(deliveryWindow.min);
      const windowEnd = new Date(deliveryWindow.max);

      const today = new Date();
      const daysUntilLatest = Math.ceil(
        (windowEnd - today) / (1000 * 60 * 60 * 24)
      );

      return {
        status,
        confidence,
        windowStart,
        windowEnd,
        daysUntilLatest,
        message: ui_suggestion.recommended_message,
        action: ui_suggestion.recommended_action,
      };
    }
    ```

    The `status` field moves through `dispatched` → `in_transit` → `out_for_delivery` → `delivered`. `confidence_level` is `"High"`, `"Medium"`, or `"Low"` — use it to decide whether to show the delivery window or a vaguer message.
  </Step>

  <Step title="Show the cardholder">
    Use `ui_suggestion.recommended_message` as your display string. Varmo generates this message based on the current status, delivery window, and the cardholder's inferred locale — you can render it verbatim without additional formatting.

    ```jsx CardDeliveryStatus.jsx theme={null}
    export function CardDeliveryStatus({ deliveryData }) {
      const { recommended_message, recommended_action } = deliveryData.ui_suggestion;
      const { status } = deliveryData;

      return (
        <div className="delivery-status-card">
          <p className="status-label">Card delivery status</p>
          <p className="status-value">{status.replace("_", " ")}</p>
          <p className="status-message">{recommended_message}</p>
          {recommended_action === "Activate" && (
            <button className="activate-cta" onClick={onActivate}>
              Activate your card
            </button>
          )}
        </div>
      );
    }
    ```
  </Step>

  <Step title="Handle delivery">
    When `status` reaches `"delivered"` or `ui_suggestion.recommended_action` is `"Activate"`, prompt the cardholder to activate their card. Do not wait for both conditions — either one is sufficient to trigger the activation flow.

    ```javascript handle-delivery.js theme={null}
    function shouldPromptActivation(response) {
      const { status } = response;
      const { recommended_action } = response.ui_suggestion;

      return status === "delivered" || recommended_action === "Activate";
    }

    function handleStatusUpdate(response) {
      if (shouldPromptActivation(response)) {
        showActivationPrompt();
      } else {
        updateDeliveryStatusUI(response);
      }
    }
    ```

    Route cardholders to your activation flow as soon as this condition is met. Delaying the prompt increases the risk that the card sits unactivated.
  </Step>
</Steps>

<Tip>
  Store the timestamp of each successful poll response. Before making a new request, check whether your last poll was less than an hour ago — if so, skip the call and use the cached response. Varmo's delivery predictions update at most once per hour, so polling more frequently than that returns the same data and adds unnecessary latency to your system.
</Tip>
