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:
21is the dashboard. Copy it from the dialog.344is the table on that dashboard. Also from the dialog.formatcan bejson,csv, orxlsx. Leave it off and you get JSON.filtersis 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:
past30daysends 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.
csvis comma separated, with a header row.xlsxis an Excel workbook.jsonis 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:fromandtoweren't two realYYYY-MM-DDdates 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.





