Key Takeaway
When an Adalo external collection returns nothing, the cause is almost always one of four things: the API response is not shaped the way Adalo expects, the auth header is missing or wrong, the pagination parameters do not match your API, or the magic text fields are mapped to keys that do not exist in the response. Start in the Test tab, read the raw response, and fix the shape first. Everything else is downstream of that.
Adalo external collections are the feature that lets your no-code app talk to a real API instead of Adalo's built-in database. When they work, they are genuinely useful. When they do not, the app shows an empty list, no error message, and no obvious clue about why. This guide walks through the actual reasons records do not show up, in the order you should check them, with the exact fixes. It is written for someone staring at a blank list view at 11pm wondering what they did wrong. Usually you did not do anything wrong. Adalo is just very particular about the shape of what comes back.
How Adalo external collections actually work
An external collection is a mapping between four REST endpoints (list all, get one, create, update, delete) and a set of named properties Adalo can bind to magic text. Adalo calls your GET all endpoint, expects a specific JSON shape back, reads the records out of it, and matches each property you defined to a key in each record. If any link in that chain breaks, the collection silently returns nothing. There is no loud error. That silence is the single most frustrating part of debugging this, and it is why you have to inspect each step deliberately.
Before changing anything in your app, open the collection's Test tab in the Adalo editor. This is the most important tool you have, and most people skip it.
Read the HTTP status first: what each code points to
The very first signal you get is the HTTP status code in the Test tab. It narrows the problem before you even look at the body. Here is the status-to-cause mapping, which is the fastest comparison you can run when a collection comes back empty.
| Status code | What it almost always means | Where to fix it |
|---|---|---|
200 with empty list | Request worked, but Adalo cannot find the records in the body | Response shape and array path (Step 2) |
401 / 403 | Auth rejected: missing, malformed, or misplaced credentials | Auth headers (Step 3) |
404 | Wrong URL, wrong path, or a typo in the endpoint | The endpoint URL (Step 1) |
429 | Rate limit hit: too many requests too fast | API plan limits, or a proxy that caches |
500 / 502 | The API itself errored, not Adalo | Your backend or the third party |
Read the code, jump to the matching step, and skip the rest. A 200 with an empty body is the trickiest case because nothing looks broken. That one almost always traces back to the response shape, which is Step 2.
Step 1: Read the raw response in the Test tab
In the external collection editor, every endpoint has a Test button. Click it and look at the raw JSON Adalo gets back, not the parsed preview. You are checking three things, in this order:
- Did the request even succeed? Use the status table above. A 200 with a body is good. A 401 or 403 means auth is wrong (jump to Step 3). A 404 means the URL is wrong. A 500 means your API itself errored.
- Is the body valid JSON? If your API returns HTML (a login page, an error page, a Cloudflare challenge), Adalo cannot parse it and the collection stays empty. Paste the raw response into a JSON validator if you are unsure.
- Where are the records inside the JSON? This is the part that breaks most often. Note the exact path to the array of records.
If the Test tab shows your records, your API is fine and the problem is in mapping (Step 5). If the Test tab shows an error or an unexpected shape, fix that first. Do not touch the app screens until the Test tab returns clean data.
Step 2: Match the response shape Adalo expects
This is the number-one reason records do not show. Adalo expects the list endpoint to return a JSON object with the array of records nested under a key, and you tell Adalo which key in the "Response: Array of records is found at" field. So the right way to think about this is not "does my API return data" but "does my API return data in the exact container Adalo reads from." The table below contrasts the shape that works against the shapes that quietly fail.
| What your API returns | What to put in "array found at" | Likely result |
|---|---|---|
[ {...}, {...} ] (bare array) | nothing fits cleanly | Often empty. Wrap the array in an object first. |
{ "records": [ {...} ] } | records | Works. This is the reliable shape. |
{ "data": { "items": [ {...} ] } } | data.items | Works. Use the dotted path. |
{ "Data": [ {...} ] } mapped to data | wrong case | Empty. Case mismatch returns nothing. |
A note on bare arrays, because the advice online is inconsistent. Adalo historically struggles with a bare top-level array, and the dependable approach is to point the "array of records is found at" field at a named key under an object, as shown in the working rows above. This is not a claim that a bare array can never render in any version of the editor. It is that the supported, predictable setup is an array nested under a key. If you are seeing an empty list and your API returns a bare array, wrap it in an object and set the path to that key. That single change fixes a large share of empty collections.
If your records are nested deeper, you give Adalo the dotted path. For a response like { "data": { "items": [ ... ] } } the path is data.items. Get this exactly right, including capitalization. Data and data are different keys, and a single wrong character returns an empty collection with no warning.
One more shape requirement: every record needs a unique identifier, and Adalo defaults to a field named id. If your records use _id, uuid, or recordId instead, you must tell Adalo which field is the identifier. A missing or non-unique id field causes records to render incorrectly, collapse into one another, or fail to open detail screens.
Step 3: Fix the auth headers
If the Test tab returns 401 or 403, the API rejected your credentials. The usual culprits:
- Header name typos. It is
Authorization, notAuthorisationorAuth. Check the exact spelling your API documents. - Missing the token prefix. Many APIs expect
Bearer YOUR_TOKEN, with the word Bearer and a space before the token. Pasting just the token fails. Some APIs useToken YOUR_TOKENor a raw key with no prefix. Match your API's docs precisely. - Header vs query parameter. Some APIs want the key as a query parameter (
?api_key=...) rather than a header. Putting it in the wrong place returns 401 even though the key is correct. - Headers set on the wrong endpoint. In Adalo, auth headers are configured per endpoint or globally depending on how you set up the collection. If you added the header only to GET all but not to GET one, list views work and detail views 401. Add the header to every endpoint that needs it.
A fast sanity check: run the exact same request in a tool like Postman or a curl command with the same header. If it works there and fails in Adalo, you have a typo or a placement difference between the two. If it fails in both, the credential itself is the problem.
Step 4: Get pagination right
Adalo paginates external collections, and it appends pagination parameters to your GET all request. If those parameters do not match what your API expects, you get one of two failure modes: only the first page of records shows, or the collection returns nothing because your API rejects unexpected query parameters.
Adalo's default pagination uses offset-style parameters. Your API might use:
- Offset and limit (
?offset=0&limit=20) which matches Adalo's default reasonably well. - Page and per-page (
?page=1&per_page=20) which does not match the default and needs adjustment. - Cursor-based (a token pointing to the next page) which Adalo's simple pagination cannot follow at all.
If your API uses page-based or cursor-based pagination and Adalo is sending offset-based parameters, the API either ignores them (so you only ever see the default first page) or errors. The practical fixes, in order of preference:
- Configure the pagination fields in Adalo to match your API's parameter names where the editor allows it.
- Have your API accept Adalo's parameters. If you control the backend, the cleanest fix is to make your endpoint understand
offsetandlimitand return the full expected shape. - Add a proxy layer. When you do not control the API and its pagination is incompatible, a thin middleware (a small serverless function, Make, or Xano) sits between Adalo and the API, translates Adalo's request into what the API wants, and reshapes the response into the object-wrapped array Adalo expects. This also solves Step 2 shape problems in one move.
If you are testing with a small dataset, pagination problems can hide because everything fits on one page. Test with more records than your page size so a broken second page actually shows up.
Step 5: Map magic text to keys that exist
Say the Test tab returns clean data, auth is fine, and pagination is set, but the list shows rows that are blank or show the wrong value. Now the problem is property mapping. Each property you defined in the collection points to a key inside a record. Two things go wrong here:
- The property is mapped to a key that does not exist. If your record has
full_namebut you named the property's sourcename, magic text binds to nothing and renders blank. Check the exact key names in the raw response and match them character for character. - Nested values are not flattened. If a record contains
{ "author": { "name": "Jane" } }, Adalo's property mapping works best with top-level keys. Deeply nested objects are hard to bind to magic text. The reliable fix is to flatten the response in a proxy so the record has a top-levelauthor_namekey.
Also confirm the property types match. A number coming back as a string, or a date in a format Adalo does not recognize, will display but behave oddly when you sort, filter, or use it in logic. When a filter on an external collection returns nothing, a type mismatch on the filtered field is a common cause.
Why records still do not show: the quick triage
If you have done all five steps and the list is still empty, run this triage. It maps the symptom to the layer that is broken.
| Symptom | Most likely cause |
|---|---|
| Test tab shows error / no data | Auth, URL, or the API itself (Steps 1 and 3) |
| Test tab shows data, app list is empty | Wrong array path or bare top-level array (Step 2) |
| Only the first page of records appears | Pagination parameter mismatch (Step 4) |
| Rows render but fields are blank | Magic text mapped to keys that do not exist (Step 5) |
| List works, detail screen 401s or is empty | Missing auth or id mapping on the GET one endpoint |
| Filters return nothing | Type mismatch on the filtered field (Step 5) |
A few practical habits make this much faster. Test in a published preview, not just the editor, because some auth and CORS behavior differs. Change one thing at a time. And keep the raw Test tab response open in a separate window so you can compare your property names against the real keys side by side.
When a proxy is the real answer
Notice how many of the fixes above end with "put a small proxy in front of the API." That is not a coincidence. Adalo's external collections are happiest when the API returns exactly the shape they want: an object wrapping an array, top-level flat keys, offset and limit pagination, and a clean id field. Real third-party APIs rarely do all of that. A thin translation layer (a serverless function, Xano, or a Make scenario) that reshapes requests and responses solves shape, pagination, and nesting problems at the same time, and it gives you one place to handle auth and rate limits. If you find yourself fighting the same four problems on every collection, build the proxy once and stop fighting.
FAQ
Why is my Adalo external collection empty even though the API works?
The most common reason is the response shape. Adalo expects a JSON object with the records nested under a key, and you must enter that exact key path in the "array of records is found at" field. A bare top-level array, a deeper nesting than you specified, or a capitalization mismatch all return an empty collection with no error. Open the Test tab, read the raw JSON, and set the array path to match exactly.
How do I fix a 401 error in an Adalo external collection?
A 401 means the auth header is wrong. Check the header name spelling (it is Authorization), make sure you included the correct prefix (often Bearer followed by a space and the token), and confirm whether the API wants the key as a header or as a query parameter. Also verify the header is set on every endpoint, not just GET all, or your detail screens will 401 while the list works.
Why does only the first page of my external collection load?
Your API's pagination does not match what Adalo sends. Adalo appends offset-style parameters by default. If your API uses page and per-page, or cursor-based pagination, it ignores Adalo's parameters and keeps returning the first page. Configure the pagination fields to match your API, change the API to accept offset and limit, or put a proxy in front to translate between the two.
How do I map nested JSON fields to magic text in Adalo?
Adalo binds magic text most reliably to top-level keys in each record. If your data is nested, like an author name inside an author object, the cleanest fix is to flatten it before it reaches Adalo by reshaping the response in a proxy so the record has a top-level key like author_name. Then map the property to that flat key.
Do I need to wrap my API response in an object for Adalo?
In most cases, yes. Adalo's external collections work most reliably when the records live inside an object, like { "records": [ ... ] }, and you point Adalo at the records key. A bare top-level array often returns nothing. If you control the API, wrap the array. If you do not, a small proxy can wrap it for you.
The bottom line
Debugging Adalo external collections is mostly a process of elimination: read the status code and raw response in the Test tab, match the shape Adalo expects, fix the auth header, align pagination, and map magic text to keys that actually exist. Work top to bottom and most empty-list problems resolve in under an hour. The deeper truth is that no-code platforms like Adalo trade flexibility for speed, and the place that trade shows up is exactly here, in the gap between what a real API returns and what the builder can parse. You can close that gap yourself with a proxy, and plenty of people do.
Some teams, though, do not want to own that maintenance at all. They want the app to work and to stay working without anyone on staff babysitting an API mapping. That is the model we run at Rehost. We are a small Los Angeles team that designs, builds, hosts, monitors, and operates custom apps and websites for businesses. Your team never logs into a builder or a dashboard. You send a plain message describing the change you want, and we ship it. The integrations, the proxies, the auth, and the response-shape headaches are ours to handle, not yours. You own the app, the App Store and Google Play developer accounts, the domain, the code repository, and your customer data, and all of it is portable if you ever leave. Business plans start at around $950/mo as of 2026, billed by monthly active users, with no setup fee and month to month terms. A custom website typically launches in under a week and a full app build in about two weeks. If you would rather build it yourself, this guide is genuinely all you need. If you would rather it just be handled, see how the done-for-you model works, run the numbers on the app calculator, or tell us what you are trying to build.