Skip to main content

Download Reporting Data by API

Covers creating an API token, finding a table's ids from the API access dialog, setting date and location filters, and what the error responses mean.

The tables on your dashboards only show part of the data (5000 Rows) behind them. That's fine for reading on screen, but not much use if you're building a spreadsheet model or loading the numbers into your own system.

You can pull the complete table through our API instead. Every row, for whatever date range you ask for, as JSON, CSV, or Excel.

What you need

  • A Vendora login that can view reports. If you can open the dashboard in the portal, you can export from it.

  • A way to send an HTTP request. A terminal, Postman, or your own code all work.


There's no separate API account to apply for and nothing to install.

Step 1: Create an API token

Open Profile Page in the portal from top right. Look for the API tokens card.

Click Generate token and choose how long it should last: 30 days, 90 days, 1 year, or never. We'd suggest 90 days for most setups.

Copy the token straight away. We only show it once. What we store on our side is a hashed version, so nobody can look the token up afterwards, including our support team. If you lose it, generate a new one.


Three things to know about these tokens:

  • The token acts as you. It carries your permissions, and we check them again on every request. If your access changes next month, the token's access changes with it. You can't reach anything through the API that you can't already see in the portal.

  • Revoking works immediately. Click Revoke next to a token and the next request using it fails.

  • You can keep 20 tokens at once. Use a separate token for each integration, so revoking one thing doesn't break everything else.

Step 2: Find the table you want

Open the dashboard in the portal and set the filters the way you want them: dates, locations, whatever that table offers.

Then open the Download menu on the table and click API access.

The dialog builds the request for that table using the filters you just set. So the easiest way to work is to get the table looking right on screen first, then open this dialog and copy the request that produces it.

Pick your file type at the top, then use whichever tab suits you:

  • Terminal gives you a complete command you can paste and run.

  • Set up by hand splits it into the URL, the header, and the body. Use this one for Postman or if you're writing code.

Below that, What you can change lists every filter the table accepts and the value currently applied to it. Those names are what you'll use in your request body.


Replace <YOUR_TOKEN> with the token from Step 1 and you're ready to go.

Step 3: Send the request

A finished request looks like this:

curl -X POST 'https://external-api.vendora.io/v1/reporting/dashboards/21/tables/344?format=csv' \   -H 'Authorization: Bearer vnd_api_your_token_here' \   -H 'Content-Type: application/json' \   -d '{"filters":{"date":{"from":"2026-08-01","to":"2026-08-31"}}}'

What the pieces mean:

  • 21 is the dashboard. Copy it from the dialog.

  • 344 is the table on that dashboard. Also from the dialog.

  • format can be json, csv, or xlsx. Leave it off and you get JSON.

  • filters is where you set your filters.

Setting filters

Filter names come from the What you can change list, and they match the filter labels on the dashboard. Values can be text, a number, true or false, or a list.

{   "filters": {     "date": { "from": "2026-08-01", "to": "2026-08-31" },     "location": ["loc_abc123", "loc_def456"]   } }

Get a name wrong and the response tells you which ones the table actually accepts, so you shouldn't need to guess twice:

{   "error": "unknown_filter",   "message": "Unknown filter \"stores\". This table accepts: date, location, platform." }


Dates

Dates take a start and an end:

{ "filters": { "date": { "from": "2026-08-01", "to": "2026-08-31" } } }


Both dates are included in the range, and both use YYYY-MM-DD. They're read the same way the date picker on the dashboard reads them, so your export will match what people see on screen.

Send the dates you actually want, every time. If a table has a date filter and you leave it out, the request is refused rather than quietly pulling your whole history. Sending {"filters":{}} does not mean "give me everything".

For scheduled jobs you can also send a relative window as plain text, like "past30days" or "thismonth". These work out their own dates when the query runs.

Two of them catch people out:

  • past30days ends yesterday. Today isn't included.

  • past30days~ does include today, but it adds today on top of the 30 days, so you get 31 days rather than a shifted window.

If someone is going to read the output or check it against another figure, use explicit from and to dates. Save the relative windows for jobs that run unattended.

Filters you leave out

Any filter you don't send falls back to the dashboard's own default. Sometimes that's what you want, but some dashboards default to something narrow like yesterday only, so it's safer to be explicit.

What comes back

The response is the file itself, named after the table.

  • csv is comma separated, with a header row.

  • xlsx is an Excel workbook.

  • json is an array of row objects, one per row.

There's no paging and nothing to follow up on. One request gives you the whole file.

Please Note: Depending upon how much data you are trying to download, the API can take anywhere between 1-5 mins to give a response.

When something goes wrong

Errors come back as a small piece of JSON with an error code and a message.

  • 400 unknown_filter: a filter name this table doesn't have. The message lists the valid ones.

  • 400 missing_date_range: the table has a date filter and you didn't send a date.

  • 400 invalid_date_range: from and to weren't two real YYYY-MM-DD dates in the right order.

  • 400 invalid_request: an id that isn't a number, a file format we don't support, or a body we couldn't read.

  • 401 invalid_token: the token is missing, wrong, expired, or revoked.

  • 403 insufficient_scope: the token isn't valid for this API, or your account can't view reports.

  • 403 forbidden: your account can't be used for reporting exports. Your admin will need to look at it.

  • 404 unknown_table: there's no table with that id on that dashboard.

  • 404 not_found: your account doesn't have reporting access to this data.

  • 409 identity_incomplete: your Vendora account has no email address on it, which reporting needs.

  • 429 too many requests: you've gone over a rate limit. See the next section.

Two of these come up more than the rest.

401 invalid_token is deliberately vague. Every failed authentication returns exactly the same response, so the message won't tell you which part was wrong. Check that you copied the whole token including everything after the dot, that the header reads Authorization: Bearer followed by your token, and that the token hasn't expired or been revoked in your Profile.

404 not_found means your account can't reach that data. It doesn't mean the table is missing. We return 404 rather than 403 on purpose, so the API can't be used to work out what exists. If you can open the dashboard in the portal but the API gives you a 404, ask your Vendora admin to check that your role covers reporting for that business.

Limits

Exports are limited to 10 requests a minute, because each one runs a real query against the reporting warehouse.

Both limits belong to your user account rather than to each token, so making a second token won't give you a second allowance. If you have two jobs that both need to run heavily at the same time, set them up under separate Vendora users.

When you need a lot of data, widen the date range instead of looping through lots of small requests. One request for the month is quicker than 30 requests for each day.

On size, we don't cap the number of rows. The practical ceiling is around a million. Files are put together in memory rather than streamed, so anything up to tens of thousands of rows is comfortable.

Looking after your tokens

These tokens carry your own access, so treat them like a password:

  • Keep them in a password manager or an environment variable. Not in your code, a shared document, or a chat message.

  • Use one token per integration, so you can revoke one without affecting the others.

  • Revoke tokens you've stopped using.

  • Set an expiry where you can, rather than choosing Never. A token that runs out on its own is safer than one sitting in a script nobody owns.

If you think a token has leaked, revoke it first and create the replacement second. Revoking takes effect on the very next request.

Need a hand?

If a request isn't doing what you expect, send us the two ids from the URL, the filters you sent, and the error code you got back. That's usually enough for us to tell you what's happening.

Did this answer your question?