---
title: "Compare two profile queries as one call tree"
method: POST
path: "/api/{org_id}/{stream_name}/profiles/diff"
tags: ["Profiles"]
---

# Compare two profile queries as one call tree

`POST /api/{org_id}/{stream_name}/profiles/diff`

## Request

- Base URL: `https://api.openobserve.ai` (the document declares no server; this is the origin it was published from)
- URL: `https://api.openobserve.ai/api/{org_id}/{stream_name}/profiles/diff`
- Auth: API key in header `Authorization`
- TypeScript: <https://skmtc.dev/openobserve/apis/openobserve-api-http/docs/api/:org_id/:stream_name/profiles/diff/post.ts> (a function with typed inputs; its response is checked against the schema)

Merges the baseline and comparison queries and folds both into one call tree where each node carries both sides' values, for a differential Flame Graph and a Top Table of changes. Both sides need the same `profile_type` and `profile_unit`.

## Path parameters

- `org_id` string, required
- `stream_name` string, required

## Request body

- ProfilesDiffBody
  - `baseline` ProfilesQueryBody, required
    - `data_source` string, nullable
    - `end_time` integer
    - `filters` ProfileFilter[]
      - `key` string, required
      - `op` string
      - `value` string, required
    - `group_by` string, nullable: Label column that splits `series` into `groups` (series endpoint only).
    - `group_limit` integer, nullable: Groups returned before the rest fold into one `others` group: 1..=50, default 10.
    - `max_nodes` integer, nullable
    - `profile_type` string, nullable
    - `profile_unit` string, nullable
    - `service_name` string, nullable
    - `start_time` integer: Missing reads as 0 so `parse_required_time_range` reports it, not the JSON parser.
    - `step` string, nullable
    - `timeout` integer, nullable
  - `comparison` ProfilesQueryBody, required
    - `data_source` string, nullable
    - `end_time` integer
    - `filters` ProfileFilter[]
      - `key` string, required
      - `op` string
      - `value` string, required
    - `group_by` string, nullable: Label column that splits `series` into `groups` (series endpoint only).
    - `group_limit` integer, nullable: Groups returned before the rest fold into one `others` group: 1..=50, default 10.
    - `max_nodes` integer, nullable
    - `profile_type` string, nullable
    - `profile_unit` string, nullable
    - `service_name` string, nullable
    - `start_time` integer: Missing reads as 0 so `parse_required_time_range` reports it, not the JSON parser.
    - `step` string, nullable
    - `timeout` integer, nullable
  - `max_nodes` integer, nullable

## Response `200`

Success

- ProfilesDiffResponse
  - `baseline_total` integer, required: Baseline total over all its stacks; above `root.before_total` when `truncated`.
  - `comparison_total` integer, required: Comparison total over all its stacks; above `root.total` when `truncated`.
  - `profile_type` string, required
  - `root` object, required: Call tree: `total` / `self` are the comparison side, `before_*` the baseline.
  - `took` integer, required
  - `top` object[], required: One row per function from both sides, largest share change first (pre-truncation).
  - `tree_truncated` boolean, required: True when the call tree was cut to `max_nodes` and light nodes folded into `other`.
  - `truncated` boolean, required: True when either side exceeded the unique-stack limit.
  - `unit` string, required

## Other responses

- `400`: Invalid request
- `403`: Forbidden
- `500`: Failure

---

[API](https://skmtc.dev/openobserve/apis/openobserve-api-http.md) - [All operations](https://skmtc.dev/openobserve/apis/openobserve-api-http/llms.txt) - [OpenAPI document](https://skmtc.dev/openobserve/apis/openobserve-api-http/revisions/0529b8a10252?raw)
