---
title: "Answer one report"
description: "One report, in the uniform envelope every key returns: a headline, a series (points), and — depending on the report's shape — rows for a breakdown, matrix for a cohort grid, or table for a…"
canonical_url: "https://twominutebilling.com/help/developers/api-reference/report-dashboards/answer-one-report"
---
# Answer one report

> One report, in the uniform envelope every key returns: a headline, a series (points), and — depending on the report's shape — rows for a breakdown, matrix for a cohort grid, or table for a…

<api-operation method="GET" path="/v1/businesses/{biz}/reports/{key}">
<template v-slot:docs="">

One report, in the uniform envelope every key returns: a headline, a series (`points`), and — depending on the report's shape — `rows` for a breakdown, `matrix` for a cohort grid, or `table` for a reconciling waterfall. `format=csv` returns the SAME answer as a file, from the same resolver, so the download and the screen cannot disagree.

`granularity` is independent of `range`: it re-cuts the preset's own span rather than widening it, and is REFUSED with a 400 — never ignored — on any shape with no series to re-cut, because honouring it silently would let a reader believe a table had been re-cut. `group_by` is likewise refused unless the report declares that dimension. Where a report supports a previous-period comparison it declares `comparable` and its answer carries one, including the BASIS the pair was cut on — a partial period is never compared against a complete one.

## Path parameters

<table>
<thead>
  <tr>
    <th>
      Parameter
    </th>
    
    <th>
      Type
    </th>
    
    <th>
      Required
    </th>
    
    <th>
      Description
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        biz
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <strong>
        yes
      </strong>
    </td>
    
    <td>
      Business id (biz_…)
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        key
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <strong>
        yes
      </strong>
    </td>
    
    <td>
      A report key from the catalogue, including a variant's key.
    </td>
  </tr>
</tbody>
</table>

## Query parameters

<table>
<thead>
  <tr>
    <th>
      Parameter
    </th>
    
    <th>
      Type
    </th>
    
    <th>
      Required
    </th>
    
    <th>
      Description
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        range
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      no
    </td>
    
    <td>
      The period to report on.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        currency
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      no
    </td>
    
    <td>
      Report in this currency. Omitted, money is converted into the business default and <code>
        converted
      </code>
      
       says so — a mixed-currency book cannot be summed raw.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        group_by
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      no
    </td>
    
    <td>
      Only a dimension the report declares; anything else is a 400.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        granularity
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      no
    </td>
    
    <td>
      How the period is split into buckets.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        aging_interval
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      no
    </td>
    
    <td>
      How wide the receivables ageing ladder's rungs are, in days. <code>
        standard
      </code>
      
       (the default) is the ladder as it has always been: monthly rungs to six months, then one rung to a year. A number gives uniform rungs of that many days out to a year, the last rung absorbing the remainder, then the same open-ended tail. Each rung NAME carries its own boundaries, so a row printed at any interval drills into the invoices behind it through the same <code>
        ar_bucket
      </code>
      
       filter. Refused with a 400 — never ignored — on a report that is not an ageing ladder, and on a width outside the set above. The catalogue's <code>
        aging_intervals
      </code>
      
       says which reports take it.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        customer_filter
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      no
    </td>
    
    <td>
      Narrow the CUSTOMERS the figure is computed from, as <code>
        <dimension>:<value>
      </code>
      
       — <code>
        country:DE
      </code>
      
      , <code>
        country:DE,IN
      </code>
      
      , or <code>
        country:unknown
      </code>
      
       for customers with none recorded. A predicate over a stored dimension, never a stored segment: a filter the stored dimensions cannot express is refused by name (400) rather than answered by rebuilding the book per slice on every read. Reports that do not carry the dimension refuse it too.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        format
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      no
    </td>
    
    <td>
      <code>
        csv
      </code>
      
       returns the same answer as a file.
    </td>
  </tr>
</tbody>
</table>

## Status codes

<table>
<thead>
  <tr>
    <th>
      Status
    </th>
    
    <th>
      Meaning
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        200
      </code>
    </td>
    
    <td>
      Success
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        400
      </code>
    </td>
    
    <td>
      An unknown range, or a granularity or breakdown this report refuses
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        404
      </code>
    </td>
    
    <td>
      No such business, or no such report key
    </td>
  </tr>
</tbody>
</table>
</template>

<template v-slot:request="">

```bash [Request]
curl "$TMBILLING_URL/v1/businesses/biz_XXXXXXXXXXXX01/reports/seats" \
  -H "Authorization: Bearer $TMBILLING_API_KEY"
```

</template>

<template v-slot:response="">
<code-group>

```json [200 OK]
{}
```

```json [400 Bad Request]
{
  "error": {
    "type": "invalid_request_error",
    "message": "An unknown range, or a granularity or breakdown this report refuses"
  }
}
```

```json [404 Not Found]
{
  "error": {
    "type": "invalid_request_error",
    "message": "No such business, or no such report key"
  }
}
```

</code-group>
</template>
</api-operation>


## Sitemap

See the full [sitemap](https://twominutebilling.com/sitemap.md) for all pages.
