Using Report Data Access (RDA)

How to structure your data access requests for fast, reliable results — including best practices to optimize performance.

How data access works

The Data Access API provides read-only access to Fusion reporting views. These views were designed for broad reporting across the Fusion platform, meaning they often contain a large number of columns and can span millions of rows depending on the dealership.

All views are accessed through a single GET endpoint. Unlike Fusion's purpose-built APIs, RDA views return everything by default — every column, every matching row — unless you tell them not to. That means the quality of your results depends entirely on how you structure your request.

When a dedicated API exists for the data you need, the API is generally the preferred method — APIs are optimized for specific use cases and include built-in business rules and validation. RDA is the right tool when you need read-only access to data that isn't available through an API, or when you need a broad reporting view across Fusion data.

Your requests run against the customer's shared SQL database — the same database that Fusion relies on for day-to-day dealership operations. A well-structured request returns fast and has minimal impact. A poorly structured one can affect database performance for every user at that dealership. Large initial data pulls are recommended to run outside of customer business hours or at a time that will be least impactful to performance.

Do

  • Use a select clause on every request — only ask for the columns you need
  • Use filter to narrow results — use AddDate or LastUpdate as a delta for incremental syncs
  • Make calls synchronously — one at a time, wait for the response
  • Run large initial data pulls outside of customer business hours or when least impactful
  • Use the smallest view that gives you the data you need
  • Page through results at a reasonable page size (100–500)

Don't

  • Request all columns — this returns the entire view width and can slow things down
  • Use the sort parameter — sorting is done on the database; sort in your app instead
  • Fire multiple requests in parallel — this stacks concurrent load on the database
  • Run large initial data pulls during peak customer business hours — this competes with the tools dealership staff rely on
  • Use a large view when a smaller one has the data you need
  • Assume an empty filter means "give me everything quickly" — it means the opposite
Select clause
Can reduce payload significantly
Filters
Can cut query time substantially
No sort
Can reduce unnecessary DB load

Endpoint

All RDA requests go through a single endpoint:

https://api.karmak.io/ops/DataAccess/Frw/{view}[?page][&pagesize][&filter][&select]

The view name is found in the URL section of each view's documentation page. Some view properties are version-specific — make sure you've selected the correct Fusion version for the customer.

Data Access API reference ›

Select

RDA views can contain dozens of columns. The select parameter tells the API to return only the ones your application actually needs. This is the single biggest thing you can do to improve performance.

Do: Include a select clause on every request. Unless your application truly needs every column in a view, you should always specify only the ones you use.

Don't: Omit the select clause. Without it, the API returns every column in the view, which can increase query time, payload size, and database load.

syntax
select={columnname},{columnname},{columnname}
Examples
ParameterWhat it does
select=UserNamereturns only the UserName field
select=UserName,FirstName,LastNamereturns UserName, FirstName, and LastName

Filtering

Filters control which rows are returned. Without them, you're asking the API to scan and return every record in the view — which on a busy dealership could be hundreds of thousands of rows.

Do: Filter by date range for incremental syncs, by branch when you only need specific locations, or by any criteria that narrows results to what your app actually processes.

Don't: Send requests with no filter. Unfiltered requests on large views take longer to process and return significantly more data than most applications need.

Incremental sync tip: most RDA views include AddDate and LastUpdate columns. These can be used as a delta to pull only new or recently changed records since your last sync. For example, filtering on LastUpdate[GT]2025-05-01T00:00:00 returns only records modified after that date. Store the timestamp of your last successful sync and use it as your next filter value — this can be significantly more efficient than pulling the full dataset every time.
syntax
filter={columnname}[{operation}]{criteria}
  • Specify the filter parameter once, even with multiple criteria
  • Separate multiple criteria with commas
  • URL encode values containing spaces or special characters
  • Use pipe | to separate values with the IN operator
Examples
ParameterWhat it does
filter=CustomerKey[EQ]123456Customer Key = 123456
filter=InvoiceID[LTE]555667,InvoiceStatus[EQ]OpenInvoice ID <= 555667 and status is Open
filter=InvoiceDate[GT]01-01-2023,InvoiceStatus[IN]paid|postedInvoice Date after 1/1/2023 and status is Paid or Posted
Filter operations
CodeMeaning
EQequals
LTless than
LTEless than or equal to
GTgreater than
GTEgreater than or equal to
NEnot equal to
INin
EQ and NE support the keyword NULL. Example: filter=invoiceID[EQ]NULL returns records where Invoice ID is null. filter=invoiceID[NE]NULL returns records where Invoice ID has data.
Supported date/time formats
FormatExample
MM-DD-YYYY HH:MM:SS11-08-2023 08:00:00
YYYY-MM-DD HH:MM:SS2023-11-08 08:00:00
YYYY-MM-DDTHH:MM:SS2023-11-08T08:00:00

Pagination

Use page and pagesize to retrieve data in manageable chunks. Page numbering starts at 1. Requesting a page beyond the available data returns an empty result.

Do: Make calls synchronously. Send a request, wait for the response, then send the next one. Use reasonable page sizes (100–500 records).

Don't: Send multiple page requests at the same time. Parallel calls stack concurrent queries on the shared SQL database and can cause timeouts for your integration and for dealership users.

syntax
page={pagenumber}&pagesize={pagesize}
Examples
ParameterWhat it does
page=1&pagesize=100start at page 1, return 100 results
page=12&pagesize=500start at page 12, return 500 results
How paging works under the hood: RDA paging calculates the entire result set up to and including the requested page. Higher page numbers require progressively more processing. Using filters and a select clause to reduce the total result set can improve paging performance across all pages.
Recommended page size: a page size between 100 and 500 works well for most use cases. Smaller page sizes mean more round trips but lighter individual queries. Larger page sizes reduce the number of calls but increase the processing time and payload for each request. Start with 500 and adjust down if you're seeing slow responses or timeouts on views with a large number of columns.

Sorting

The sort parameter tells the database to order the result set before returning it. This adds processing overhead to every request and, on large views, can significantly slow down response times.

Do: Retrieve the data without sorting and sort it in your application after receipt. The default sort order is sufficient for consistent paging.

Don't: Use the sort parameter unless you have a specific technical reason that can't be solved client-side. Most integrations don't need server-side sorting.

If you do need to use sort:

syntax
sort={order}{columnname},{order}{columnname}
  • Specify the sort parameter once, even with multiple columns
  • Default order is ascending
  • Prefix a column name with - for descending
Examples
ParameterWhat it does
sort=invoiceIDascending by Invoice ID
sort=-invoicestatus,-invoiceIDdescending by Invoice Status, then descending by Invoice ID
If using both sort and select, every sort column must be included in the select parameter or the request will fail.
Sort + select compatibility
ExampleResult
select=UserName&sort=UserIDfail
select=UserName,FirstName,LastName&sort=UserID,AddDatefail
select=UserName,UserID&sort=UserIDpass
select=UserName,UserID,LastName&sort=UserID,UserNamepass
Views have a default sort column pre-defined. When using select without sort, data is sorted by the default column (if included in select) or the first column in your select list.

Aliasing

Aliasing lets you rename columns in the response. Useful when your application expects different field names than what the view returns.

syntax
select={columnname}:{newname},{columnname}:{newname}
Examples

select=UserName:User returns:

[
  { "User": "MyUser" },
  { "User": "MyUser2" }
]

select=UserName:User,UserNumber:Id,DOB:Birthday returns:

[
  {
    "User": "MyUser",
    "ID": "1",
    "Birthday": "03-02-1973"
  },
  {
    "User": "MyUser2",
    "ID": "2",
    "Birthday": "01-21-1985"
  }
]