# Variables and secrets

> Where a value can come from, in which order Mariner looks, how to keep credentials out of exports, and how to capture values from a response so the next request already has them.

## Where values come from

Mariner resolves each `{{name}}` through a cascade. The last layer that defines the key wins:

1. **Global variables** — attached to no workspace and no collection. Nothing in the app creates them; they arrive with an imported `.mariner` package.
2. **The collection's own variables** — imported from a Postman collection as *‹Collection› Variables*. There is nothing to pick here: they apply to everything inside that collection.
3. **The active workspace environment** — the one shown in the **● ENV** pill.
4. **Request-local variables** — the **Variables** tab of the request itself. Use them for a value that makes sense nowhere else; they win over the environment.

The order is Postman's own (global < collection < environment < local), so a collection you imported sends the same request in both apps. Hover a token in the URL to see which layer its value came from.

A variable's value may itself contain other tokens; Mariner resolves up to five levels deep and leaves a cycle as literal text.

## Built-in dynamic variables

These produce a fresh value on every send and never need defining:

| Token | Value |
|---|---|
| `{{$uuid}}` / `{{$guid}}` | A random UUID |
| `{{$timestamp}}` | Seconds since 1970 |
| `{{$isoTimestamp}}` | The current time in ISO 8601 |
| `{{$randomInt}}` | An integer between 0 and 1000 |

## Path variables

A segment such as `/users/:id` becomes a row in the **Path variables** section of the **Params** tab. Fill it in and the segment is replaced at send time; leave it empty and Mariner blocks the send until you do. Port numbers and `https:` are not mistaken for path variables — only a colon that follows a slash counts.

## Secrets

Tick **Secret** on a variable and its value is masked wherever it appears: the environment list, the URL preview, the generated code. Reveal it on demand with the eye toggle.

- Secret values are **left out of every export** — the `.mariner` package and the Postman file keep the key and its flags with an empty value, so the recipient fills in their own.
- The generated-code sheet has an **Include secrets** switch that is off by default, and warns you when you turn it on.
- Secret variables sync with iCloud like any other variable, because they are part of the environment. Credentials entered in the **Auth** tab are different: those go to the macOS Keychain and never leave the Mac — see [Authentication](/docs/auth).

<aside class="callout" data-label="AGENTS">
When an agent talks to Mariner over the MCP server, secret values are never returned — the tools report only whether a secret is set or empty.
</aside>

## Capture values from a response

The **Post-Response** tab holds capture rules: after a response arrives, take a value out of it and write it into a variable. A login request that saves its token is the classic case.

1. Click **Add rule** and choose a **source**: a JSON path in the body (`$.token`, `$.data.items[0].id`), a header, a cookie, or the status code.
2. Choose the **target**: the active workspace environment or the request's own variables, and the key to write.
3. Optionally restrict the rule to a status range. The default is 200–299, so a failed login never overwrites a good token.

Every rule shows a live preview against the last response, and the value picker lets you click a node in the JSON instead of typing its path. Results appear in the **Captures** tab of the response. During a collection run captures from one request are visible to the next, which is what makes a *login → list → detail* sequence work unattended.

The JSON path syntax is deliberately small: `$`, dotted keys and numeric indexes. No wildcards, no filters.

---
Source: https://marinerhttp.dev/docs/variables · Mariner docs
