# Typography and titles

Everything the API draws (point labels, route labels, neighbor labels, the title) uses one font setting. The basemap keeps its own fonts.

## Fonts and weights

Three families are bundled: `noto-sans` (the default), `noto-serif` and `noto-sans-mono`. `fontweight` sets the weight for all labels; the nearest bundled weight is used, so asking for 650 gives you a real weight rather than a faux-bold.

```http
GET /v1/map.png?area=Zlínský+kraj&poi=place:Zlín&poi=place:Kroměříž&font=noto-serif&fontweight=700&w=400&h=300
```

![Bold serif labels](/docs/images/examples/font-serif-bold.png)

Parameters: [`font`](/docs/reference/parameters.md#param-font), [`fontweight`](/docs/reference/parameters.md#param-fontweight). A single label can override the weight, see [Points and labels](/docs/guides/points-and-labels.md).

## Fallback

Text is drawn as vector paths from the font files, so output does not depend on fonts installed on the server. If the chosen font lacks a character, that character falls back to Noto Sans, then to Noto Sans Mono (which, for example, has arrows such as "→" that the serif lacks). Latin scripts with diacritics are covered. The bundled fonts also cover several non-Latin scripts (see below); CJK is not covered, so supply your own font for it.

```http
GET /v1/map.png?from=50.1,14.26&to=40.64,-73.78&profile=geodesic&fromlabel=PRG&tolabel=JFK&font=noto-serif&title=PRG+→+JFK&titlepos=bottom&titlealign=center&w=520&h=300
```

![An arrow rendered through glyph fallback](/docs/images/examples/fallback-arrow.png)

## Non-Latin scripts

Labels and titles in Arabic, Hebrew, Devanagari, Thai, Georgian and Armenian work with any font family. Text is shaped with HarfBuzz, so Arabic letters join, Devanagari conjuncts form and Thai marks stack. Mixed right-to-left and left-to-right text (for example "Cairo القاهرة 2026") is reordered for display. For each script the server falls back automatically to a bundled Noto font, at the same weight as your chosen font. CJK is not supported yet; supply your own font for it.

```http
GET /v1/map.png?poi=30.0444,31.2357|label:القاهرة&poi=31.7683,35.2137|label:ירושלים&poi=28.6139,77.209|label:नई+दिल्ली&poi=13.7563,100.5018|label:กรุงเทพมหานคร&poi=41.7151,44.8271|label:თბილისი&w=520&h=320
```

![Labels in several scripts](/docs/images/examples/typography-scripts.png)

## Custom fonts

Send your own TTF, OTF or WOFF in `font.family` as a `data:` URI, or an `https` URL on a host the operator allows (`WHEREBOX_FONT_HOSTS`, falling back to the icon hosts; see the [configuration reference](/docs/reference/configuration.md)). This is POST only.

This example is parsed but not rendered in the docs build, because it needs a font host that you configure:

```json
{
  "area": "Czechia",
  "font": { "family": "https://fonts.example.com/brand-regular.woff2", "weight": 500 },
  "pois": [{ "place": "Chřiby" }],
  "width": 468,
  "height": 280
}
```

Missing glyphs still fall back to the bundled fonts. Size and fetch time are capped by the server, and a rejected font is a `400 bad-request`.

## The title band

`title` adds a band above or below the map. The band is **inside** your `w × h`: the map gets the remaining height, so the image size does not change.

```http
GET /v1/map.png?area=Czechia&title=Czechia+and+its+neighbors&titlepos=bottom&titlealign=center&neighbors=name&w=468&h=300
```

![A centered title band below the map](/docs/images/examples/title-bottom.png)

Long titles shrink and then get an ellipsis, so they never wrap. Parameters: [`title`](/docs/reference/parameters.md#param-title), [`titlepos`](/docs/reference/parameters.md#param-titlepos), [`titlealign`](/docs/reference/parameters.md#param-titlealign), [`titlesize`](/docs/reference/parameters.md#param-titlesize), [`titleweight`](/docs/reference/parameters.md#param-titleweight), [`titlecolor`](/docs/reference/parameters.md#param-titlecolor), [`titlebg`](/docs/reference/parameters.md#param-titlebg). Title options without `title` are an error.

Colors follow the preset: the dark preset gets a dark band with light text. In POST there are a few more options (divider, padding):

```json
{
  "area": "Zlínský kraj",
  "title": {
    "text": "Zlín Region",
    "position": "top",
    "align": "left",
    "size": 20,
    "weight": 700,
    "background": "#f3efe6",
    "dividerColor": "#c9c2b0",
    "padding": 12
  },
  "width": 420,
  "height": 320
}
```

![A styled title band](/docs/images/examples/title-post.png)
