> ## Documentation Index
> Fetch the complete documentation index at: https://docs.lerian.studio/llms.txt
> Use this file to discover all available pages before exploring further.

# Reporter SDK and embedding

> Integrate Reporter from your own software: the REST surface that carries every operation, the base URL and auth model, a first call, the Go SDK, and the pattern for running Reporter behind a service you already operate.

Reporter's **REST API is the complete surface**. Templates, reports, data sources, deadlines, the template builder, and metrics are all HTTP calls. Nothing exists only inside a client library, and nothing exists only inside the Console.

Start there. This page covers what you authenticate with, what your base URL looks like, what a first call returns, where the Go SDK saves you work, and how to run Reporter behind a service your own users already talk to.

## Authenticating

***

One scheme protects every operation: a bearer token on the `Authorization` header.

```
Authorization: Bearer <token>
```

Access Manager authorises each call against the resource behind the path — templates, reports, data sources, deadlines, metrics, or streaming — and the action, which is the HTTP verb. A token granted read access to reports can list and download them, and gets a `403` on create. Failures answer `application/problem+json`, so parse the problem document rather than the status line alone.

The token also carries the isolation scope of the call. Reporter resolves it from the credential itself, so no operation takes a scoping header from your client and no header widens what a token already permits.

## Base URL

***

The base path is `/v1`, with no product segment in front of it. Every path on this page appends to that:

```
https://reporter.example.com/v1
```

Three content-type rules follow from the surface itself. Template upload and update are `multipart/form-data`, because a template is a `.tpl` file. Report creation is `application/json`. A download streams the rendered bytes with the `Content-Type` of the output format and a `Content-Disposition` filename.

List operations take `limit` and `page`, 10 and 1 by default. The largest page is `MAX_PAGINATION_LIMIT`, which each deployment sets and which defaults to 100. A `limit` above that ceiling is rejected, not reduced.

## Your first call

***

<Steps>
  <Step title="Confirm the token and the base URL">
    ```bash theme={null}
    curl -s "https://reporter.example.com/v1/templates" \
      -H "Authorization: Bearer $TOKEN"
    ```

    A `200` with a template list proves both. A `401` means the token; a `404` means the base URL.
  </Step>

  <Step title="Request a report">
    ```bash theme={null}
    curl -s -X POST "https://reporter.example.com/v1/reports" \
      -H "Authorization: Bearer $TOKEN" \
      -H "Content-Type: application/json" \
      -H "X-Idempotency: daily-balance-2026-07-28" \
      -d '{
        "templateId": "0196b270-a315-7137-9408-3f16af2685e1",
        "filters": {
          "midaz_onboarding": {
            "account": { "status": { "eq": ["ACTIVE"] } }
          }
        }
      }'
    ```

    The response is `201` with the report in `Processing`. Generation runs asynchronously.
  </Step>

  <Step title="Wait for a terminal state, then download">
    ```bash theme={null}
    curl -s "https://reporter.example.com/v1/reports/$REPORT_ID" \
      -H "Authorization: Bearer $TOKEN"

    curl -s "https://reporter.example.com/v1/reports/$REPORT_ID/download" \
      -H "Authorization: Bearer $TOKEN" -o report.pdf
    ```

    Download requires `Finished`.
  </Step>
</Steps>

Send `X-Idempotency` on every report request, and on template upload for the same reason. Repeat a request that is still running and you get an error instead of a second report. Repeat one that already finished and Reporter replays the original report, marking the response `X-Idempotency-Replayed: true`. Derive the key from your own request identifier and a retry costs nothing.

A report is created once and kept: create, get, list, download are its four operations. How long a rendered file lives is a lifecycle policy on the storage bucket, not an API call.

## Reading data sources

***

An operator configures data sources through environment variables, so the API over them is read-only. Use it to discover what your templates can reference:

```bash theme={null}
curl -s "https://reporter.example.com/v1/data-sources" \
  -H "Authorization: Bearer $TOKEN"
```

Each entry carries the config name that templates address, plus its tables and fields. Fetch one by identifier with `/v1/data-sources/{dataSourceId}`.

## The Go SDK

***

[`lerian-sdk-golang`](https://github.com/LerianStudio/lerian-sdk-golang) ships a `reporter` package alongside the other Lerian products. It is a convenience over the calls above for template and report work: it acquires an OAuth2 client-credentials token, refreshes it, and hands back typed results and paginated iterators.

Configure it with the same `https://<host>/v1` base URL you use with cURL, plus the client ID, the client secret, and the token URL of your authorization server, and a request timeout.

```go theme={null}
report, err := client.Reporter.Reports.Get(ctx, reportID)
if err != nil {
    return err
}

if report.Status == "Finished" {
    data, err := client.Reporter.Reports.Download(ctx, reportID)
    if err != nil {
        return err
    }

    if err := os.WriteFile(reportID+"."+report.Format, data, 0o600); err != nil {
        return err
    }
}
```

`Download` returns the rendered bytes in the report's own format. Write them to disk, as above, or stream them to your caller.

The SDK covers a slice of the product, not all of it. It carries template create, get, list, and delete, and report create, get, list, and download. Data sources, template update, deadlines, the template builder, metrics, and the streaming manifest are REST calls. Mixing both in one integration is normal and expected: the package where it fits, plain HTTP everywhere else.

## Running Reporter behind your own service

***

Reporter is a service you deploy, not a library you link. To put it behind an application your customers already use, keep the credentials on your side and call Reporter server to server. Four rules keep that boundary clean.

**Never hand a Reporter token to a browser.** Your service authenticates your user, decides whether that user may run this report, and then makes the call with its own token.

**Answer immediately with an identifier.** Report creation returns in `Processing`. Return that identifier to your caller and let your own status endpoint expose progress.

**Learn about completion once.** Poll `GET /v1/reports/{id}` on a modest interval, or subscribe to Reporter's report events and stop polling. See [Reporter events](/en/reporter/reporter-events).

**Proxy the download.** The download endpoint streams bytes to an authenticated caller, so your service fetches them and re-serves them under its own auth.

<Note>
  A `Partial` report means some data sections failed while others succeeded, and its metadata names the failing sections. Treat it as a signal about a data source or a filter, and decide in your own service what your users should see.
</Note>

## Next steps

***

<CardGroup cols={2}>
  <Card title="Reporter REST API" icon="code" href="/en/reporter/reporter-rest-api">
    Every operation, grouped by the job it does.
  </Card>

  <Card title="Reporter events" icon="tower-broadcast" href="/en/reporter/reporter-events">
    The event contract, and how to subscribe instead of polling.
  </Card>

  <Card title="API quick start" icon="rocket" href="/en/reference/reporter/reporter-developer-quick-start">
    Upload a template and generate a report with cURL.
  </Card>

  <Card title="Error list" icon="triangle-exclamation" href="/en/reference/reporter/reporter-error-list">
    Reporter's error codes and what resolves them.
  </Card>
</CardGroup>
