File Format (.pro)
A .pro file is a JSON-encoded snapshot of captured traffic. Probe writes it when you save a session (Cmd+S on a recording tab) or export entries via the right-click menu. The same file shape was previously called .gmp (“Guide MITM Proxy”); both extensions are still accepted on import.
Probe also writes two related shapes — collection exports for a multi-entry export and request exports for a single entry. The importer routes by the JSON format field, not the file extension.
Top-level shape
Section titled “Top-level shape”The first key tells the importer what’s inside:
{ "format": "guide-session" | "guide-collection" | "guide-request", "version": 1, ...}Probe trusts the format value over the extension — you can rename a file from .json to .pro (or vice-versa) and import will still work.
guide-session
Section titled “guide-session”The full snapshot a saved tab produces. Lives in ~/.probe/sessions/<id>.json for the in-app sessions list; written to a user-chosen path on Save Session….
{ "format": "guide-session", "version": 1, "id": "01HXY7M0QZJ8R5ZF6Q4Y8MR8GA", "name": "Auth flow — staging", "createdAt": 1731081900123, "entries": [ { /* LogEntry */ }, { /* LogEntry */ } ]}| Field | Type | Description |
|---|---|---|
format | string | Must be "guide-session". |
version | integer | 1 today. Bumped on a breaking format change. |
id | string | Session id (ULID-style). |
name | string | Display name. Editable via the Sessions manager. |
createdAt | integer | Milliseconds since epoch, UTC. |
entries | array | One LogEntry per captured request. |
guide-collection
Section titled “guide-collection”The export format for a multi-entry export (right-click on selected rows → Export).
{ "format": "guide-collection", "version": 1, "exportedAt": 1731082000000, "entries": [ /* LogEntry, ... */ ]}Same entries shape as a session, without the session-level id and name. On import, each entry is added to the active recording tab.
guide-request
Section titled “guide-request”A single-entry export. Useful for sharing one request without surrounding noise.
{ "format": "guide-request", "version": 1, "entry": { /* LogEntry */ }}LogEntry shape
Section titled “LogEntry shape”The same LogEntry JSON appears inside every Guide format above:
{ "id": 142, "method": "POST", "url": "https://api.example.com/v1/users", "statusCode": 201, "timestamp": 1731081900123, "clientAddr": "Chrome", "reqHeaders": { "content-type": "application/json", "authorization": "Bearer ..." }, "reqBody": "{\"name\":\"Ada\"}", "resHeaders": { "content-type": "application/json", "content-length": "21" }, "resBody": "{\"id\":1,\"name\":\"Ada\"}", "contentType": "application/json", "durationMs": 184, "reqSize": 124, "resSize": 21}| Field | Type | Notes |
|---|---|---|
id | integer | Unique per session. |
method | string | HTTP method. |
url | string | Full URL the client sent. MITM-intercepted entries carry the explicit :443/:80 port. |
statusCode | integer | 0 if no response was received (request errored mid-flight or was aborted). |
timestamp | integer | Milliseconds since epoch, UTC. |
clientAddr | string | Process name for loopback traffic, IP address for remote phones. May be empty. |
reqHeaders | object | Lower-cased keys, single value per key. |
reqBody | string | null | Raw body as text. Bodies above the size cap or non-text content show as "[binary or oversized body]". |
resHeaders | object | Same conventions as reqHeaders. |
resBody | string | null | Same conventions as reqBody. |
contentType | string | null | Sniffed from the response. |
durationMs | integer | null | Total request → response time. |
reqSize | integer | Bytes-on-the-wire estimate of the request. |
resSize | integer | Bytes-on-the-wire estimate of the response. |
Fields not in the JSON are tolerated by LogEntry.fromJson — defaults are applied (statusCode = 0, empty headers, etc.). That makes forward-compatibility easy: a future version that adds new fields can be loaded by an older Probe.
Compatibility
Section titled “Compatibility”.gmpfiles — same JSON shape, accepted by every importer. Probe writes.profor new exports..jsonfiles — accepted; the importer sniffsformat.- Renamed extensions — fine. Content-sniffing wins over the extension.
What’s NOT in the file
Section titled “What’s NOT in the file”- No request/response that was already discarded for size — bodies stripped at capture time stay stripped. Sessions are wire-level, not browser-level.
- No HAR support today. Probe doesn’t read or write HAR.
- No environment data, scripts, breakpoints, or rules. A
.proonly carries traffic. Compose collections (with environments and scripts) live separately under~/.probe/compose/<collection-id>.json.
See also
Section titled “See also”- Sessions — the user-facing feature this format underpins.
- Internal REST API — fetch saved sessions via
/api/v1/session-tabs/saved/{id}.