How to properly URL encode multiple sorting parameters for Airtable API requests

I’m working with the Airtable API and need help building the correct URI encoding for sorting multiple columns with different directions.

My sorting configuration looks like this:

const sortConfig = [
  { column: "name", order: "ascending" },
  { column: "price", order: "descending" },
  { column: "type", order: "ascending" }
];

Current attempt at building the query string:

let queryString;

sortConfig.forEach(item => {
  console.log(item.column, item.order);
  queryString += `&sort%5B0%5D%5Bfield%5D=${encodeURIComponent(
    item.column
  )}&sort%5B0%5D%5Bdirection%5D=${item.order}`;
});

console.log(queryString);

This code isn’t working correctly and I suspect the URL encoding format is wrong. I’m getting unexpected results when making API calls. Has anyone successfully implemented multi-field sorting with the Airtable API? What’s the proper way to structure these query parameters?

had the same airtable sorting headache last month. here’s what nobody mentioned - check if you’re using asc/desc vs ascending/descending. airtable’s api only accepts the short versions (asc, desc), not the full words. that might be causing your weird results even after fixing the indexing. also, strip that leading & from your query string before adding it to your base url or you’ll get messed up request formatting.

Both answers nail the technical stuff, but here’s something practical that helped me. When I was debugging similar Airtable API calls, I’d test the query string separately from the actual request. Build your sort parameters, log the final URL, then throw it into Postman or your browser to check if it looks right before hitting Airtable’s endpoint. The docs show examples with unencoded brackets like sort[0][field]=name, but when you’re building programmatically, those brackets need encoding. What tripped me up at first was that Airtable respects sort parameter order - the first field gets priority. If your results still look weird after fixing the indexing and initialization problems, double-check that your sort priority matches what you expect.

This tripped me up badly with Airtable’s sorting API - parameter order in your URL matters for sort priority. Spent hours debugging why my records wouldn’t sort right. Turns out I was building parameters out of sequence because async operations screwed up my forEach loop. Fix was making sure sort[0] always comes before sort[1] in the final query string, not just having the right index numbers. Also, double-check your field names match exactly what’s in Airtable - spaces, special characters, everything. One typo and the entire sort silently fails without throwing an error. I validate field names against the base schema before building sort parameters now to catch this stuff early.

Everyone’s covering the technical stuff, but you’re overcomplicating this.

I’ve written tons of parameter building code for internal APIs. The manual string concatenation, encoding headaches, debugging hell when parameters don’t line up - been through it all.

Now I just toss this into an automation platform and let it handle the messy bits. Takes 2 minutes to set up proper Airtable integration with sorting vs writing and debugging parameter code.

The platform handles encoding automatically, manages array indexing correctly, and I can see exactly what parameters get sent. When API requirements change (they always do), I update the flow instead of rewriting code.

Saved me 10 hours last month adding dynamic sorting across multiple Airtable bases. Drag, drop, configure, done.

Check it out: https://latenode.com

Your problem is using [0] for every sorting parameter - they’re overwriting each other. Each one needs its own index. I hit this same issue with Airtable sorting last year. Here’s the fix: javascript let queryString = ''; sortConfig.forEach((item, index) => { queryString += `&sort%5B${index}%5D%5Bfield%5D=${encodeURIComponent(item.column)}&sort%5B${index}%5D%5Bdirection%5D=${item.order}`; }); See how I’m using index from forEach? That creates unique positions like sort[0], sort[1], sort[2]. Also initialize queryString as an empty string, not undefined. Your URL should end up looking like: sort[0][field]=name&sort[0][direction]=ascending&sort[1][field]=price&sort[1][direction]=descending This way Airtable can parse each sorting rule in the right order.

You’ve got multiple issues stacking up here. Been fighting this exact battle with APIs for years.

Your main problem is treating Airtable’s sort params like a simple key-value situation. It’s actually an array structure that needs proper indexing.

Here’s what I do when building complex query params:

function buildSortQuery(sortConfig) {
  const params = [];
  
  sortConfig.forEach((item, index) => {
    params.push(`sort[${index}][field]=${encodeURIComponent(item.column)}`);
    params.push(`sort[${index}][direction]=${item.order}`);
  });
  
  return params.join('&');
}

This keeps everything clean and avoids the undefined concatenation mess. Plus you can easily debug by logging the params array.

One thing that bit me hard - Airtable expects exact field names. If your column name has spaces or weird characters, it has to match perfectly. I always test with simple field names first, then add complexity.

Also worth checking your base URL construction. Make sure you’re not accidentally doubling up ampersands or missing the question mark before your first parameter.

When this stuff goes wrong, I copy the final URL and test it directly in a REST client. Saves tons of debugging time.

Emma nailed the index issue, but you’ve got another bug lurking.

Your queryString isn’t initialized. When you do queryString += something on an undefined variable, you get “undefined” stuck at the beginning. Classic mistake.

let queryString = ''; // Fix this first

sortConfig.forEach((item, index) => {
  queryString += `&sort%5B${index}%5D%5Bfield%5D=${encodeURIComponent(item.column)}&sort%5B${index}%5D%5Bdirection%5D=${item.order}`;
});

Better approach though - use URLSearchParams:

const params = new URLSearchParams();

sortConfig.forEach((item, index) => {
  params.append(`sort[${index}][field]`, item.column);
  params.append(`sort[${index}][direction]`, item.order);
});

const queryString = params.toString();

Handles encoding automatically and saves you from URL encoding hell. Way easier to debug too.

I use this with complex APIs all the time. Never fails.