Contact us
Guides

Run reports from your application

Fetch report data through the API: find a report, supply prompt values, run it, and map the columns and rows into your own interface.

Yurbi reports can be run through the API and the results rendered anywhere. This guide covers the full sequence, including prompts, which is where most integrations need the detail.

The sequence

SearchReports              find the report ID
GetReportMetadataById      fetch the report's runtime object
ReplacePromptCollection    supply values, if the report has prompts
GetReportData              run it and read Columns + Data

The metadata object returned in step two is what step four executes. Pass it through unchanged apart from prompt values.

1. Find the report

SearchReports matches on name and returns items the calling user can see:

curl -X POST "https://your-yurbi-server.com/api/library/SearchReports" \
  -H "Content-Type: application/json" \
  -d '{ "sessionToken": "YOUR_SESSION_TOKEN", "searchstring": "Revenue" }'

Results include dashboards as well as reports. Dashboards have itemtype 0 and are not valid report IDs, so filter them out. To browse rather than search, use GetAllLibraryTree followed by GetListByFolderID.

2. Get the report metadata

curl -X POST "https://your-yurbi-server.com/api/Report/GetReportMetadataById" \
  -H "Content-Type: application/json" \
  -d '{ "sessionToken": "YOUR_SESSION_TOKEN", "ReportID": "1738259678",
        "isTarget": false, "PreviousMetadata": null, "Criteria": null }'

The response has two parts: Report, the definition, and Prompts, an array of any values the report asks for at run time. When Prompts is empty or null, skip to step four.

An unknown ID returns ErrorCode 586 inside Report.

3. Supply prompt values

Each prompt describes one input. The fields that matter are:

Field Purpose
PromptField.DisplayFieldName What to label the input in your interface
PromptField.Fieldtype The value's type — num, cha, dat and so on
isBetween The prompt takes a range, so set both values
isInList The value may be a comma-separated list
isSkipable The prompt may be skipped by setting isSkipped
LowValue Where you set the value
HighValue The upper bound when isBetween is true

Set values on LowValue and HighValue. Those are the fields the API reads.

To offer a picker rather than a free-text box, call GetFieldValues with the prompt object; it returns the selectable values as {key, val} pairs.

Apply the values with ReplacePromptCollection, sending the prompts back in the order and length the metadata gave you — values are matched to prompts by position:

{
  "Reportobj": { "...": "the metadata object from step 2" },
  "Prompts": [
    { "...": "prompt 0", "LowValue": "1115", "HighValue": "" },
    { "...": "prompt 1", "LowValue": "2024-01-01", "HighValue": "2026-12-31" }
  ]
}

The response is the metadata with those values compiled into the report's criteria. Pass that to step four.

Two notes on values:

  • Send explicit dates. For a date prompt, GetFieldValues returns relative expressions such as [Today] and [Last Month] for use in interface pickers. Resolve them to a date before sending.
  • Applying one prompt at a time. ReplacePrompt applies a single prompt and returns updated metadata. It compiles only the prompt you pass, so call it once per prompt, feeding each response into the next call as Reportobj.

4. Run the report

{
  "sessionToken": "YOUR_SESSION_TOKEN",
  "IsDrillDown": false,
  "DrillDownCriteria": null,
  "Reportobj": { "...": "metadata, with prompts applied" },
  "TargetReportobj": null
}

Check HasError, not ErrorCode. On this endpoint a failed execution returns HasError: true with the reason in ErrorMessage, while ErrorCode stays 0.

const res = await runReport(metadata);
if (res.HasError) {
  throw new Error(res.ErrorMessage);
}

5. Read the results

Columns describes the shape and Data holds the rows, one object per row keyed by column:

{
  "HasError": false,
  "Columns": [
    { "headerText": "Customer", "key": "Customer_ID", "dataType": "number",
      "yurbitype": "num", "dataFormatString": null, "columngroup": "" },
    { "headerText": "Tickets",  "key": "Ticket_ID",   "dataType": "number",
      "yurbitype": "num", "dataFormatString": null, "columngroup": "" }
  ],
  "Data": [ { "Customer_ID": 1115, "Ticket_ID": 10 } ],
  "etime": "79"
}

Use headerText for column labels and key to read each row. yurbitype tells you how to format the value — see Field type codes. etime is the execution time in milliseconds.

Rendering a table takes only Columns and Data; the remaining fields are interface bindings used by Yurbi's own components.

const rows = res.Data.map(row =>
  res.Columns.map(col => row[col.key])
);

Practical notes

Results are not paged. A report returns every row it produces, so a detail report over a large table can return several megabytes. Where you need a summary, run a report built with an aggregate or a TopN limit rather than fetching detail rows and reducing them in your own code.

Running without prompts. Set supressprompts true on GetReportData to run a prompted report without supplying values. The result is unfiltered by those prompts, which suits scheduled extracts where the filtering happens downstream.

Reuse metadata across runs. The metadata object for a given report is stable, so an application that runs the same report with different prompt values can fetch it once and apply values per run.

Row-level security still applies. Data security policies constrain results by the calling user, so run reports under the end user's own session rather than a shared account if tenants must stay separated. See Multi-tenant provisioning.

Endpoints used