> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.termina.ai/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.termina.ai/_mcp/server.

# Derived Metrics

GET https://app.termina.ai/api/v1/group/{group_id}/deal/{deal_id}/data/financials/derived-metrics

Get derived financial metrics (IS + BS ratios) for the company associated with the deal.

In addition to the fields listed in the schema, each entry may include
**category growth rates** for revenue and/or GTV.  Exactly one of the
following sets is present, determined by the top-level ``freq``:

- **Monthly (freq=M):** ``revenue_cmgr3``, ``revenue_cmgr6``, ``revenue_cmgr12``,
  ``gtv_cmgr3``, ``gtv_cmgr6``, ``gtv_cmgr12``
- **Quarterly (freq=Q):** ``revenue_cqgr1``, ``revenue_cqgr2``, ``revenue_cqgr4``,
  ``gtv_cqgr1``, ``gtv_cqgr2``, ``gtv_cqgr4``
- **Annual (freq=A):** ``revenue_cagr1``, ``revenue_cagr2``, ``revenue_cagr4``,
  ``gtv_cagr1``, ``gtv_cagr2``, ``gtv_cagr4``

These fields are only present when income statement data exists.
GTV fields are only present when GTV data is available.

Reference: https://docs.termina.ai/api-reference/data/financials/get-derived-metrics

## Authentication

- `Authorization` header (bearer token, required) — Bearer authentication of the form `Bearer <token>`, where token is your auth token.

## Servers

- `https://app.termina.ai` (Production server, default)
- `https://app.termina.dev` (Development server)
- `http://localhost:8000` (Local development server)

## Request

### Path parameters

- `group_id` (integer, required)
- `deal_id` (integer, required)

## Response

### 200

Successful Response

- `freq` (enum, required) — The frequency of the derived metrics data.
  - Allowed values: `M`, `Q`, `A`
- `unit` (string, optional, default: USD) — The display unit for monetary values.
- `derived_metrics` (list of DerivedMetricEntry, optional, nullable) — Derived financial metrics combining IS and BS computations.

## Errors

### 422 Unprocessable Entity Error

Validation Error

- `detail` (list of ValidationError, optional)

## Types

### DerivedMetricEntry

Category growth rates (revenue and GTV) appear as dynamic fields. You get exactly one of: cmgr (monthly), cqgr (quarterly), or cagr (annual)—never more than one set. Which set is present is determined by the top-level `freq`: monthly → revenue_cmgr3, revenue_cmgr6, revenue_cmgr12, gtv_cmgr3, gtv_cmgr6, gtv_cmgr12; quarterly → revenue_cqgr1, revenue_cqgr2, revenue_cqgr4, gtv_cqgr1, gtv_cqgr2, gtv_cqgr4; annual → revenue_cagr1, revenue_cagr2, revenue_cagr4, gtv_cagr1, gtv_cagr2, gtv_cagr4. These are only present when income statement data exists.

- `date` (string, required) — The date of the derived metrics.
- `lifetime_gross_margin` (double, optional, nullable) — The lifetime gross margin, integrated over all time.
- `lifetime_operating_margin` (double, optional, nullable) — The lifetime operating margin, integrated over all time.
- `lifetime_ebitcac_margin` (double, optional, nullable) — The lifetime EBITCAC margin (Operating Income minus S&M, as a percentage of revenue), integrated over all time.
- `gross_margin` (double, optional, nullable) — Gross Margin.
- `quarterly_gross_margin` (double, optional, nullable) — Gross Margin (Rolling Q).
- `operating_margin` (double, optional, nullable) — Operating Margin.
- `quarterly_operating_margin` (double, optional, nullable) — Operating Margin (Rolling Q).
- `ebitcac` (double, optional, nullable) — EBITCAC (Operating Income minus S&M spend).
- `quarterly_ebitcac` (double, optional, nullable) — EBITCAC (Operating Income minus S&M spend), Rolling Q.
- `ebitcac_margin` (double, optional, nullable) — EBITCAC Margin.
- `quarterly_ebitcac_margin` (double, optional, nullable) — EBITCAC Margin (Rolling Q).
- `rule_of_40` (double, optional, nullable) — The rule of 40, defined as the year over year growth plus the operating margin, with slight smoothing to handle variations.
- `cac_of_40` (double, optional, nullable) — The CAC of 40, defined as the year over year growth plus the EBITCAC margin (Operating Income minus Sales & Marketing, as a percentage of revenue), with slight smoothing to handle variations.
- `magic_number` (double, optional, nullable) — The magic number, defined as the revenue growth divided by the offset sales and marketing cost, with slight smoothing to handle variations. Magic Number above 10 is treated as missing.
- `margin_magic_number` (double, optional, nullable) — The margin magic number, defined as the gross profit growth divided by the offset sales and marketing cost, with slight smoothing to handle variations. Margin Magic Number above 10 is treated as missing.
- `burn_multiple` (double, optional, nullable) — The burn multiple, defined as the cash burn divided by the revenue growth, with slight smoothing to handle variations. The operating margin is used in place of the cash burn if the cash burn is not available. Not defined if the revenue growth is negative.
- `margin_burn_multiple` (double, optional, nullable) — The margin burn multiple, defined as the cash burn divided by the gross profit growth, with slight smoothing to handle variations. The operating margin is used in place of the cash burn if the cash burn is not available. Not defined if the gross profit growth is negative.
- `roas` (double, optional, nullable) — Proxy for Return on Ad Spend (ROAS), calculated using the previous month's sales and marketing spend as a rolling approximation. Most applicable when S&M expenses are well-labeled and customer churn is high. ROAS above 20 is treated as missing.
- `margin_roas` (double, optional, nullable) — Gross Margin adjusted ROAS, applying gross margin to the standard ROAS calculation. Uses the same rolling approximation approach. Margin ROAS above 20 is treated as missing.
- `total_debt` (double, optional, nullable) — Short-term + long-term debt.
- `working_capital` (double, optional, nullable) — Current assets minus current liabilities.
- `current_ratio` (double, optional, nullable) — Current assets / current liabilities.
- `liabilities_to_equity` (double, optional, nullable) — Total liabilities / equity.
- `liabilities_to_assets` (double, optional, nullable) — Total liabilities / total assets.
- `debt_to_equity` (double, optional, nullable) — Total debt / equity.
- `debt_to_capital` (double, optional, nullable) — Total debt / (total debt + equity).
- `equity_ratio` (double, optional, nullable) — Equity / total assets.
- `debt_to_assets` (double, optional, nullable) — Total debt / total assets.
- `debt_ratio` (double, optional, nullable) — Total debt / total assets (alias).
- `tangible_assets` (double, optional, nullable) — Assets minus goodwill and intangibles.
- `tangible_equity` (double, optional, nullable) — Equity minus goodwill and intangibles.
- `current_liabilities_to_current_assets` (double, optional, nullable) — Current liabilities / current assets.
- `working_capital_ratio` (double, optional, nullable) — Working capital / current assets.
- `cash_ratio` (double, optional, nullable) — (Cash + short-term investments) / current liabilities.
- `unrestricted_cash_ratio` (double, optional, nullable) — (Cash + short-term investments - restricted cash) / current liabilities.
- `quick_ratio` (double, optional, nullable) — (Cash + short-term investments + receivables) / current liabilities.

### ValidationError

- `loc` (list of ValidationErrorLocItems, required)
- `msg` (string, required)
- `type` (string, required)
- `input` (any, optional)
- `ctx` (ValidationErrorCtx, optional)

### ValidationErrorLocItems

- string
- integer

### ValidationErrorCtx

## Examples

**Response**

```json
{
  "freq": "M",
  "unit": "USD",
  "derived_metrics": [
    {
      "date": "2024-01",
      "lifetime_gross_margin": 0.72,
      "lifetime_operating_margin": -0.35,
      "rule_of_40": 0.25,
      "magic_number": 1.2,
      "margin_magic_number": 0.6,
      "burn_multiple": 0.4,
      "margin_burn_multiple": 0.4,
      "roas": 1,
      "margin_roas": 0.6,
      "total_debt": 500000,
      "working_capital": 1200000,
      "current_ratio": 2.1,
      "debt_to_equity": 0.35,
      "revenue_cmgr3": 0.05,
      "revenue_cmgr6": 0.08,
      "revenue_cmgr12": 0.12,
      "gtv_cmgr3": 0.04,
      "gtv_cmgr6": 0.07,
      "gtv_cmgr12": 0.1
    },
    {
      "date": "2024-02",
      "lifetime_gross_margin": 0.73,
      "lifetime_operating_margin": -0.32,
      "rule_of_40": 0.28,
      "magic_number": 1.3,
      "margin_magic_number": 0.65,
      "burn_multiple": 0.38,
      "margin_burn_multiple": 0.38,
      "roas": 1.1,
      "margin_roas": 0.65,
      "total_debt": 480000,
      "working_capital": 1300000,
      "current_ratio": 2.2,
      "debt_to_equity": 0.33,
      "revenue_cmgr3": 0.06,
      "revenue_cmgr6": 0.09,
      "revenue_cmgr12": 0.13,
      "gtv_cmgr3": 0.05,
      "gtv_cmgr6": 0.08,
      "gtv_cmgr12": 0.11
    }
  ]
}
```

**SDK Code**

```python
import requests

url = "https://app.termina.ai/api/v1/group/1/deal/1/data/financials/derived-metrics"

headers = {"Authorization": "Bearer <token>"}

response = requests.get(url, headers=headers)

print(response.json())
```

```javascript
const url = 'https://app.termina.ai/api/v1/group/1/deal/1/data/financials/derived-metrics';
const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go
package main

import (
	"fmt"
	"net/http"
	"io"
)

func main() {

	url := "https://app.termina.ai/api/v1/group/1/deal/1/data/financials/derived-metrics"

	req, _ := http.NewRequest("GET", url, nil)

	req.Header.Add("Authorization", "Bearer <token>")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby
require 'uri'
require 'net/http'

url = URI("https://app.termina.ai/api/v1/group/1/deal/1/data/financials/derived-metrics")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'

response = http.request(request)
puts response.read_body
```

```java
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.get("https://app.termina.ai/api/v1/group/1/deal/1/data/financials/derived-metrics")
  .header("Authorization", "Bearer <token>")
  .asString();
```

```php
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('GET', 'https://app.termina.ai/api/v1/group/1/deal/1/data/financials/derived-metrics', [
  'headers' => [
    'Authorization' => 'Bearer <token>',
  ],
]);

echo $response->getBody();
```

```csharp
using RestSharp;

var client = new RestClient("https://app.termina.ai/api/v1/group/1/deal/1/data/financials/derived-metrics");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <token>");
IRestResponse response = client.Execute(request);
```

```swift
import Foundation

let headers = ["Authorization": "Bearer <token>"]

let request = NSMutableURLRequest(url: NSURL(string: "https://app.termina.ai/api/v1/group/1/deal/1/data/financials/derived-metrics")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```