Authentication

One header, two key classes. Getting the class wrong is the most expensive mistake you can make here, so the difference is worth two minutes.

either header works
Authorization: Bearer hv_live_xxxxxxxx_secret
x-api-key: hv_live_xxxxxxxx_secret

Two classes of key

SecretPublishable
Prefixhv_live_ / hv_test_hv_pub_live_ / hv_pub_test_
Lives onYour serverYour public web page
ScopesWhatever you grantcheck:read, products:read only
Origin-boundNoYes — only listed origins
Can writeYes, if scopedNever

Publishable keys

Use one for the widget, or for your own browser code that calls /v1/check and /v1/products. It is capped server-side to those two read scopes no matter what you request, and it only works from origins you list.

issue a publishable key
curl -X POST https://api.haavisa.com/v2/keys \
  -H "Authorization: Bearer $HAAVISA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Booking site widget",
    "kind": "publishable",
    "allowed_origins": ["https://bookings.example.com"]
  }'
response — note what was dropped
{
  "key": "hv_pub_live_xxxxxxxx_secret",
  "scopes": ["check:read"],
  "dropped_scopes": ["applications:write"],
  "dropped_reason": "Publishable keys are limited to check:read and products:read."
}

dropped_scopes names anything you asked for and did not get, so you are never building against a capability you were refused.

A publishable key with no origins permits nothing. That fails closed on purpose: forgetting to configure the allowlist must not produce a key that works everywhere.

Scopes

Test keys

hv_test_ and hv_pub_test_ work against the same host. Calls made with one are recorded for your usage graph but are never billed.

There is no separate sandbox host. That is a real difference from what you may expect, and it is stated here so you do not spend an afternoon looking for one.

The partner portal signs in differently

A human does not use an API key. The portal at <portal-url> authenticates with a single-use email link and an HttpOnly session cookie. Requiring a key to obtain a key would be a circle.