# Monitor an API behind a login

> A health page that answers "OK" tells you very little when the part that matters sits behind a login.

Source: https://infranest.io/docs/monitor-an-api-behind-a-login
Last updated: 2026-11-02

---

Monitor an API that sits behind a login, so you can catch real failures — not just a health page that says "OK" while the parts that matter are broken. This is for anyone who needs to check an API that requires signing in first.

## Overview

- A health page can look fine even when sign-in, tokens, or the actual data calls are failing.
- An **API monitor** acts like a real user: it signs in, keeps the token it gets back, and uses that token to call your API.
- If any step fails, the monitor goes down and tells you exactly which step failed and why — for example "Step 2 of 3 (GET /orders): HTTP 401".

## Set it up

1. Go to **Monitoring** and click **Add monitor**.
2. Click **Advanced monitors**, then choose **API monitor**.
3. Fill in the first request — usually your sign-in address — with its method and request body. This request is **step 1**.
4. Under **Save from this response**, name the value you need later (for example `token`), choose where it comes from and say where to find it:
   - **JSON field** — a path such as `$.access_token`;
   - **Response header** — a header name such as `X-Session-Id`;
   - **Pattern in the text** — a pattern whose first group is the value, such as `token=([a-z0-9]+)`.
5. Under **Secret values**, add anything you should not have to look at again, such as the password the sign-in uses. Then write `{{password}}` in the body of step 1 where the password goes.
6. Click **Add a step** for each call that follows. Give it a method and an address — a full address, or just a path like `/orders`, which is read against the monitor's address — and use saved values with double braces, for example a header **Authorization** with the value `Bearer {{token}}`. The value box lists every value the step can use.
7. For each step, set the status codes that count as success and, if you like, checks on the JSON it returns.
8. Click **Test connection** to try the whole flow once, then save.

<!-- screenshot: monitor-an-api-behind-a-login -->

<!-- docs-screenshots:start:monitor-an-api-behind-a-login -->

![Monitor an API behind a login](/media/cc990323-82da-4790-a572-6a3528d99e7b)

<!-- docs-screenshots:end:monitor-an-api-behind-a-login -->

## What you get

- The monitor is up only when **every** step passes. The first step that fails ends the check, and the reason names the step, the request and what went wrong. Alerts and incidents use the same words.
- On the monitor's page, **Steps** lists each request the last check made, with the status it got back and how long it took.
- Regions, how many locations must agree, and failover work exactly as they do for any other monitor.

## Good to know

- **Up to 5 steps** in all, including the first request, and up to 5 saved values per step.
- **All steps together get at most 60 seconds**, and never more than the monitor's interval. A step that would start after that time is reported as "ran out of time".
- **Secret values are stored encrypted and are never shown again** — not on the form, not through the API. To change one, type a new value; to drop one, remove it and save.
- **Saved values are never kept.** The step list shows each request as you wrote it (`/orders/{{order_id}}`), not with the values filled in, and a value that appears in a failure reason is replaced by `[hidden]`.
- The monitor's own sign-in settings (basic, digest or bearer) are only sent to steps on the same site as the monitor's address. Put anything a step on another site needs in that step's headers.

> [!WARNING]
> Headers that carry a password, key or token — **Authorization**, **Cookie**, **X-Api-Key** and the like — must use a value such as `{{api_key}}` or `Bearer {{token}}`. Put the password or key in **Secret values** and refer to it; typing it directly into the header is refused when you save.

## Troubleshooting

- **"… has no value"** — a step uses a name that no earlier step saved and no secret value has. Check the spelling, and that the step that saves it comes first.
- **"Couldn't save …"** — the response did not contain what you pointed at. Run **Test connection** and compare the path with what your API actually returns.
- **"Step 1 of 2 …: HTTP 401"** — the sign-in itself was refused. Check the secret value and the request body.

> [!TIP]
> Use **Test connection** after any change to the steps — it runs the whole flow once so you can catch a broken sign-in or a bad path before you save.
