---
title: "Coach bilan: coverage gaps and ranked sell arguments"
method: POST
path: "/api/v1/coach/bilan"
tags: ["Coach"]
---

# Coach bilan: coverage gaps and ranked sell arguments

`POST /api/v1/coach/bilan`

## Request

- Base URL: `https://atlas.hellosafe.com`
- URL: `https://atlas.hellosafe.com/api/v1/coach/bilan`
- Auth: API key in header `x-atlas-key-id` and API key in header `x-atlas-timestamp` and API key in header `x-atlas-signature`

Analyses a traveller's situation against the travel cover carried by their bank card, for the chosen destinations, and returns it as data: the card's GAPS (guarantees in default, adequately covered ones are omitted), a ranked list of arguments each with a strength and a category, the medical recommendation, a social-proof figure and an attributed quote link.

Sell-only by design: it returns the card's shortcomings, never a reason not to buy, except bilan.medical, which gives the trip's recommended medical ceiling (it follows the destination) and whether the card meets it. Copy comes back as message KEYS plus interpolation variables, not finished sentences, so you render it in your own wording. Requires a key carrying the `coach` scope, which every self-serve key now has: the sandbox answers from the real engine, and its `offer.quoteUrl` comes back null because a sandbox key credits nobody.

## Request body

- object
  - `residence` string, required: ISO 3166-1 alpha-2. Drives the health socle and the default market.
  - `destinations` string[], required: Where they travel. ISO 3166-1 alpha-2, 1 to 50 codes.
  - `card` object: Exactly one card mode: { catalogueId } | { bin } | { bank, network, tier } | { network, tier } | { none: true }. catalogueId names the exact card: take it from GET /api/v1/coach/cards (a sandbox key identifies cards by BIN or bank instead, see key.cardModes there). A BIN or { bank, network, tier } match by range: at a bank with two cards of one tier, the most basic one wins. A card that cannot be resolved never fails the call: it degrades to a baseline card and adds a code to meta.warnings.
  - `trip` object: Optional booleans, all default false.
    - `friends` boolean
    - `longTrip` boolean
    - `riskyActivity` boolean
  - `market` 'fr' | 'us' | 'ca' | 'sg' | 'my' | 'universal': Currency, formatting and health socle. Derived from residence when omitted.
  - `ref` string: Overrides the attribution ref baked into the returned quote URL.

## Response `200`

The bilan. See the guide for the full field by field description.

- object
  - `ok` boolean
  - `card` object: origin (exact | generic | baseline | none), currency, detected issuer when a BIN resolved, and `guarantees`: the gaps only.
  - `bilan` object: shouldSell, headline, `medical` (the trip's recommended medical ceiling, from 30 000 € inside the traveller's health zone to 500 000 € for the United States, and ceilingOk), social proof, focusCategories, and `arguments` sorted by strength then category. Each argument carries messageKeys + vars, not prose.
  - `destinations` string[]
  - `offer` object: quoteUrl, carrying your attribution when the key is set up with it: a tracked short link (https://atlas.hellosafe.com/r/<code>?res=..&lang=..) that counts each click in your dashboard's Links tab, then opens the HelloSafe travel form. Display it as it comes.
  - `meta` object: engineVersion, market, lang, passport and non-fatal warnings.

## Other responses

- `400`: INVALID_JSON, BAD_RESIDENCE or NO_DESTINATIONS.
- `401`: UNAUTHORIZED, STALE_TIMESTAMP or INVALID_SIGNATURE.
- `403`: SCOPE_FORBIDDEN: the key lacks the coach scope.
- `502`: AUTH_LOOKUP_FAILED or CARD_RESOLVE_FAILED.

---

[API](https://skmtc.dev/hellosafe/apis/hellosafe-travel-insurance-api.md) · [All operations](https://skmtc.dev/hellosafe/apis/hellosafe-travel-insurance-api/llms.txt) · [OpenAPI document](https://skmtc.dev/hellosafe/apis/hellosafe-travel-insurance-api/revisions/8185e81c9817?raw)
