HelloSafe Coach API

Coverage gaps and ranked sell arguments from a traveller profile and a bank card.

Operations 2

POST /api/v1/coach/bilan Coach bilan: coverage gaps and ranked sell arguments #
GET /api/v1/coach/cards Card catalogue: the banks and cards the Coach knows #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/hellosafe:hellosafe-coach-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

hellosafe-coach-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: HelloSafe Travel Insurance Coach API
  version: 2.3.2
  summary: Price and sell travel insurance from any travel product.
  description: 'A REST API that prices a trip against a multi-insurer travel insurance catalogue and returns comparable offers with their guarantees, then mints a tracked subscription link so the sale is attributed and paid as commission. Built for travel agencies, tour operators, OTAs, booking engines and travel apps that want to add travel insurance without becoming an insurer or holding a distribution licence.


    Every key ships with a free sandbox that returns deterministic fixtures in the exact live response shape, so an integration can be built and tested end to end before a single insurer is called.


    **Authentication** is a per-caller HMAC-SHA256 handshake, server to server. Send three headers:


    - `x-atlas-key-id`: your key id

    - `x-atlas-timestamp`: unix seconds, rejected beyond a 5 minute window

    - `x-atlas-signature`: `v2=` + hex HMAC-SHA256 of `${timestamp}.${METHOD}.${pathname}.${rawBody}`, keyed with your signing secret


    The signature covers the raw request body byte for byte. There is no CORS header on these responses: the signing secret must never reach a browser.'
  termsOfService: https://atlas.hellosafe.com/legal/terms
  contact:
    name: HelloSafe Atlas
    url: https://atlas.hellosafe.com/platform/api/documentation
    email: atlas@hellosafe.com
  x-logo:
    url: https://atlas.hellosafe.com/hellosafe-logo.svg
  x-providerName: atlas.hellosafe.com
  x-apisguru-categories:
  - financial
  - ecommerce
  license:
    name: Proprietary
    url: https://atlas.hellosafe.com/legal/terms
servers:
- url: https://atlas.hellosafe.com
  description: Production. Sandbox versus live is decided by your key, not by the URL.
security:
- AtlasKeyId: []
  AtlasTimestamp: []
  AtlasSignature: []
tags:
- name: Coach
  description: Coverage gaps and ranked sell arguments from a traveller profile and a bank card.
paths:
  /api/v1/coach/bilan:
    post:
      tags:
      - Coach
      summary: 'Coach bilan: coverage gaps and ranked sell arguments'
      description: '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.'
      operationId: postCoachBilan
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - residence
              - destinations
              properties:
                residence:
                  type: string
                  minLength: 2
                  maxLength: 2
                  description: ISO 3166-1 alpha-2. Drives the health socle and the default market.
                  example: FR
                destinations:
                  type: array
                  minItems: 1
                  maxItems: 50
                  items:
                    type: string
                    minLength: 2
                    maxLength: 2
                  example:
                  - TH
                  - VN
                  description: Where they travel. ISO 3166-1 alpha-2, 1 to 50 codes.
                card:
                  type: object
                  description: '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.'
                  example:
                    bin: '497010'
                trip:
                  type: object
                  description: Optional booleans, all default false.
                  properties:
                    friends:
                      type: boolean
                    longTrip:
                      type: boolean
                    riskyActivity:
                      type: boolean
                market:
                  type: string
                  enum:
                  - fr
                  - us
                  - ca
                  - sg
                  - my
                  - universal
                  description: Currency, formatting and health socle. Derived from residence when omitted.
                ref:
                  type: string
                  description: Overrides the attribution ref baked into the returned quote URL.
            examples:
              visaPremiumCard:
                summary: A French traveller in Thailand, premium Visa card
                value:
                  residence: FR
                  destinations:
                  - TH
                  card:
                    bin: '497010'
                  trip:
                    longTrip: true
                  market: fr
      responses:
        '200':
          description: The bilan. See the guide for the full field by field description.
          content:
            application/json:
              schema:
                type: object
                properties:
                  ok:
                    type: boolean
                  card:
                    type: object
                    description: 'origin (exact | generic | baseline | none), currency, detected issuer when a BIN resolved, and `guarantees`: the gaps only.'
                  bilan:
                    type: object
                    description: 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:
                    type: array
                    items:
                      type: string
                  offer:
                    type: object
                    description: '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:
                    type: object
                    description: engineVersion, market, lang, passport and non-fatal warnings.
        '400':
          description: INVALID_JSON, BAD_RESIDENCE or NO_DESTINATIONS.
        '401':
          description: UNAUTHORIZED, STALE_TIMESTAMP or INVALID_SIGNATURE.
        '403':
          description: 'SCOPE_FORBIDDEN: the key lacks the coach scope.'
        '502':
          description: AUTH_LOOKUP_FAILED or CARD_RESOLVE_FAILED.
  /api/v1/coach/cards:
    get:
      tags:
      - Coach
      operationId: getCoachCards
      summary: 'Card catalogue: the banks and cards the Coach knows'
      description: 'The bank cards the Coach knows, per country of residence: each bank, then its cards, with the name printed on the card, its picture, the tier the Coach reads from that name, and the catalogueId that names the card exactly in POST /api/v1/coach/bilan. Built for a card picker: the traveller''s bank, then their card, then the bilan with { catalogueId }. byBankTier says whether { bank, network, tier } would land on that same card: at a bank with two cards of one tier, only the most basic one is reachable that way. Travellers whose bank is not listed fall back to the generic { network, tier } profiles listed under generic. Signed like every endpoint, with an empty body: the query string is not signed. Does not consume quota.'
      parameters:
      - name: country
        in: query
        required: false
        schema:
          type: string
          minLength: 2
          maxLength: 2
        example: FR
        description: 'Country of residence, ISO 3166-1 alpha-2. Omitted: every country with a bank list (FR, US, CA, SG, MY). Any other valid code returns an empty banks list.'
      - name: lang
        in: query
        required: false
        schema:
          type: string
          enum:
          - fr
          - en
        description: 'Language of the card names. Default: French for FR, English elsewhere.'
      responses:
        '200':
          description: The catalogue.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CoachCardsResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
components:
  schemas:
    CoachCardsResponse:
      type: object
      properties:
        ok:
          type: boolean
        country:
          type:
          - string
          - 'null'
          description: The country asked for, or null when every country was listed.
        key:
          type: object
          properties:
            keyId:
              type: string
            mode:
              type: string
              enum:
              - sandbox
              - live
            cardModes:
              type: array
              items:
                type: string
                enum:
                - bin
                - bank
                - catalogueId
                - network
                - none
              description: The card modes this key may send to POST /api/v1/coach/bilan.
        countries:
          type: array
          description: Every country with a bank list, whichever country was asked for.
          items:
            type: object
            properties:
              code:
                type: string
              market:
                type: string
              banks:
                type: integer
              cards:
                type: integer
        banks:
          type: array
          items:
            type: object
            properties:
              name:
                type: string
                description: The bank name the { bank, network, tier } mode accepts.
              country:
                type: string
              logoUrl:
                type:
                - string
                - 'null'
              cards:
                type: array
                description: Most basic first.
                items:
                  type: object
                  properties:
                    catalogueId:
                      type: integer
                      description: 'Names this card exactly: send it as card.catalogueId.'
                    name:
                      type: string
                      description: The card's name as printed.
                    network:
                      type:
                      - string
                      - 'null'
                      description: visa, mastercard, amex...
                    tier:
                      type:
                      - string
                      - 'null'
                      enum:
                      - entry
                      - mid
                      - premium
                      - elite
                      - business
                      - null
                      description: The range the Coach reads from the card's name. Null when the name carries no range word.
                    byBankTier:
                      type: boolean
                      description: True when { bank, network, tier } lands on this very card.
                    imageUrl:
                      type:
                      - string
                      - 'null'
        generic:
          type: array
          description: Networks and the tiers with a generic profile of their own, for a bank that is not listed.
          items:
            type: object
            properties:
              network:
                type: string
              tiers:
                type: array
                items:
                  type: string
        tiers:
          type: array
          description: What each tier reads as on a card.
          items:
            type: object
            properties:
              tier:
                type: string
              examples:
                type: array
                items:
                  type: string
    Error:
      type: object
      properties:
        error:
          type: string
          examples:
          - UNAUTHORIZED
          - BAD_LANGUAGE
          - NO_TRAVELLERS
          - TOO_MANY_TRAVELLERS
          - QUOTA_EXCEEDED
      required:
      - error
  responses:
    BadRequest:
      description: Malformed request.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    Unauthorized:
      description: Missing, expired or invalid signature.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    Forbidden:
      description: The key does not carry the required scope.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
  securitySchemes:
    AtlasKeyId:
      type: apiKey
      in: header
      name: x-atlas-key-id
      description: Your key id, from partners.api_clients.
    AtlasTimestamp:
      type: apiKey
      in: header
      name: x-atlas-timestamp
      description: Unix seconds. Rejected beyond a 5 minute replay window.
    AtlasSignature:
      type: apiKey
      in: header
      name: x-atlas-signature
      description: v2=<hex HMAC-SHA256 of `${ts}.${METHOD}.${pathname}.${rawBody}`>.
externalDocs:
  description: Travel insurance API documentation
  url: https://atlas.hellosafe.com/platform/api/documentation
x-provenance:
  method: harvested
  publisher: HelloSafe
  source: https://atlas.hellosafe.com/openapi.json
  note: split by refine-openapis from the provider's own published document, verified by fetch (openapi/_original/*.fetch.json);
    stamped by stamp-openapi-provenance.py (roadmap#793)