Help

Upcoming database upgrades. to improve our reliability at 03:30 UTC on Feb. 25 / 7:30pm PT on Feb. 24. Some users may briefly experience slow load times or error messages. Learn more here

[API] Error requesting a single field

Topic Labels: API
8181 16
cancel
Showing results for 
Search instead for 
Did you mean: 

The following request works as expected:

https://api.airtable.com/v0/appD1JKW7PlQhRMrF/Docentes?fields=Email&fields=Status

But this one fails with status 422 Unprocessable Entity:

https://api.airtable.com/v0/appD1JKW7PlQhRMrF/Docentes?fields=Email

The response is:

{"error":{"type":"INVALID_REQUEST_UNKNOWN","message":"Invalid request: parameter validation failed. Check your request data."}}
16 Replies 16

Also, what does “array of strings” actually mean in the context of an URL-encoded parameter?

Funny thing, repeating the field works:

https://api.airtable.com/v0/appD1JKW7PlQhRMrF/Docentes?fields=Curso&fields=Curso

Clearly there’s a problem with the “array” when it has only one element.

Yes, I don’t understand the “array of elements” when it doesn’t work for one element. Airtable should explain it better in the doc

You’re right—this is a little confusing.

If you want to pass a single value, such as maxRecords, you’ll supply it as a normal query parameter. For example:

?maxRecords=5

However, if you want to pass an array, you’ll need to append [] to the end of each key.

For example, imagine you want to list records and only include two fields: “My First Field” and “My Other Field”. You’d send query parameters like this:

?fields%5B%5D=My%20First%20Field&fields%5B%5D=My%20Second%20Field

If you only wanted one field, you’d still append the [].

Our query parsing is somewhat lenient, which is why supplying the parameter multiple times works. We recommend appending the [] in all cases so that it works when you just want to supply an array with one value.

If you can, we recommend using a client library to avoid some of this. Airtable.js is our official offering, but our API docs mention a few unofficial libraries for other languages. You can use the Airtable API URL Encoder to put together a properly-formatted request if you’re not using a library.

In any case, we’ll plan to update our docs here, because this isn’t clear.

So, this is getting pretty annoying at the moment, as it is taking me almost two days to just configure airtable post request, i have tried everything ii know and have researched online, nothing seems to change, getting the same error almost all the time

Home.js:90 POST https://api.airtable.com/v0/app5aBFbyn7WropZL/contact?api_key=keyfX7UkMiODjA6fq 422 (Unprocessable Entity)
sendData @ Home.js:90

Home.js:103 Success: {"error":{"type":"INVALID_REQUEST_UNKNOWN","message":"Invalid request: parameter validation failed. Check your request data."}}

My code
`
import React, { Component, useState } from “react”;
import axios from “axios”;
import AboutUs from “…/…/component/AboutUs”;
import { Form } from “react-bootstrap”;
import Contact from “./Airtable”;
var Airtable = require(“airtable”);
var base = new Airtable({ apiKey: --------------" }).base(
“app5aBFbyn7WropZL”
);
}

const [formData, setFormData] = useState({});
const [message, setMessage] = useState("");

const handleInput = (e) => {
const copyFormData = { …formData };
copyFormData[e.target.name] = e.target.value;
setFormData(copyFormData);
};

base(“contact”).create(
[
{
fields: {},
},
{
fields: {},
},
],
function (err, records) {
if (err) {
console.error(err);
return;
}
records.forEach(function (record) {
console.log(record.getId());
});
}
);

const sendData = async (e) => {
e.preventDefault();
try {
const response = await fetch(
https://api.airtable.com/v0/app5aBFbyn7WropZL/contact?api_key=----------------”,
{
method: “post”,
body: JSON.stringify([formData]),
headers: {
“Content-Type”: “application/json”,
},
typecast: true,
}
);
const json = await response.json();
console.log(“Success:”, JSON.stringify(json));
setMessage(json.message);
} catch (error) {
console.error(“Error:”, error);
setMessage(“Error”);
}
};

return (



<div
id=“home”
className=“header-hero bg_cover d-lg-flex align-items-center”
style={{ backgroundImage: “url(assets/images/header-hero.jpg)” }}
>






<h1
style={{
fontFamily: Slack-Larsseit "Helvetica Neue", "Helvetica","Segoe UI",Tahoma,Arial,sans-serif,
letterSpacing: “-.8px”,
}}
>
Take the work experience around

entirely under your control.
{" “}
OneScrin is for everyone, from casual chat to high-powered
video collaboration.






<input
className=“main-btn”
type=“email”
id=“terms”
name=“email”
placeholder="workemail@email.com
// value={this.state.email}
// onChange={this.handleChange}
onChange={handleInput}
// onChange={this.onChange}
// disabled={this.state.isCheckBoxSelected}
style={{
marginRight: “-50px”,
marginTop: “7.5px”,
color: “white”,
backgroundColor: “transparent”,
}}
/>
<button
id=“submit-form”
name=“submit”
type=“submit”
className=“main-btn”
style={{
position: “relative”,
marginLeft: “1px”,
marginTop: “7.5px”,
}}
>
Try For Free


            <br />
            <span
              style={{
                textAlign: "justify",
                maxWidth: "29rem",
                fontSize: "11px",
              }}
            >
              {/* onChange={this.changeHandler} */}
              <input type="checkbox" /> i would like to receive email
              notifications about OneScrin and its affilliate products. By
              clicking 'Sign Up', you understand and agree to the OneScrin{" "}
              <a href="https://onescrin.com.ng/terms-of-service">
                Terms of Service
              </a>
            </span>
            <div>{message}</div>
          </div>
        </div>
      </div>
      <div
        className="header-hero-image d-flex align-items-center wow fadeInRightBig"
        data-wow-duration="1s"
        data-wow-delay="1.1s"
      >
        <div className="image">
          <img src="assets/images/home.gif" alt="Chat Room" />
        </div>
      </div>
    </div>

    <AboutUs />
    <Contact />
    {/* <PostLanding /> */}
  </header>
</div>

);
};

export default Home;

`

How does one do this in Python?

I tried
AT_url = 'https://api.airtable.com/v0/'+ base_id + '/' + table_id + '/' + record_id
AT_url += '?fields=Notes'
response = requests.get(AT_url, headers=read_headers)
and that errored out with the same INVALID_REQUEST_UNKNOWN error Michael_Cetrulo had.

I’ve also tried:
AT_url += '?fields=Notes&fields=Notes'
and
AT_url += '?fields%5B%5D=Notes'
and
AT_url += '?fields%5B=Notes%5D'
but none work.

I’m sure it’s just some formatting issue I’m getting wrong, but I can’t figure it out…

In addition, I’d like to future proof it and use the field ID. Once I have the field query fixed, would the field ID just be used in place of the field name?

@Tane_Martin
In Python my url looks like this:
https://api.airtable.com/v0/base_id/table_name?api_key=APIKEY
Then I pass the response to a Panda dataframe, where I can work with the data via python directly for that specific table.

Thanks @CH3V4L13R, but my issue is more with pulling the data only for that record and field. The problem is that my table is large enough and has enough data that the call will fail if I don’t filter it (i think the limit is 6MB). I also dont want to burden the server too much, pulling the full table for just the single cell I’m interested in. Do you have any experience filtering down to the record and/or field level in a Python call?

Also, if requesting a field using a field ID, does anyone know if the value returned keyed by the field ID? Or the field name? If it’s still keyed by the field name, that’d be a bummer since I’d have to map it back out again.

You don’t need to pull the full table, only the record that you are interested in.
Do a request on this url:
https://api.airtable.com/v0/APP_ID/TABLE/RECORD_ID?api_key=APIKEY
Send that response to PANDA so you can manipulate all your fields via Python directly.

Ahh nice @CH3V4L13R, yeah the record specific portion is working for me now. thanks

Now I’m stuck with the field id portion. Manipulation using the field names works fine, but I can’t manipulate using the field id. Have you used the Field IDs instead of the Field Names? The reason for this being so that if/when the field name is changed, it doesn’t break the code

Or alternatively, if that url can be modified to pull only a specific field (which I’ll do with the field id), that should work too. Do you know how to modify that url to add that query? That’s where I hit the issues I did above with the field query formatting

Makes sense, but I’m using the field name so I don’t think I can help you with that.
How do you retrieve the field ID in the first place?
If you check the Airtable API usages doc, it only explain to retrieve data by record level. I guess trying to be more specific and try to get at a field level is not possible but I may be wrong.

The field IDs are kind of annoying to get right now - I used the script here: Field ID instead of Field Name?

The API docs do mention very briefly how to query by field (under the “List Records” portion), but I can’t translate the javascript or @EvanHahn’s response above into Python haha

I read here: Referencing Field IDs using the API for Code Maintainability that its possible to use the field IDs in place of field names, but I think thats 1) in the query only and 2) not sure if the data is returned keyed to the ID (which would be more useful) or the name (which I think is more likely). I reached out to AT to find out on both points.

Thanks for the help!

Oh interesting wrinkle is that this works: https://api.airtable.com/v0/APP_ID/TABLE_ID?api_key=API_KEY&fields[]=FIELD_TO_FILTER_TO but only if I don’t include the record in the endpoint.

Bummer is that using the field_id in the field query doesn’t return the results by field id, only field name. So looks like I’ll have to do some mapping…

Thanks too! That’s interesting. Please follow up by sharing AT answers or any others solutions you may find out. Will certainly help others too.

So it turns out what I was attempting isn’t possible, but the AT support team had a suggestion that works the same way:

The fields parameter will only work with the “List records” call (which doesn’t include a record ID in the url) – if you’re just retrieving a single record by including that record ID in the url, then all non-empty fields will be returned and it’s not possible to specify particular fields. A potential workaround here: rather than querying the record directly by adding the record ID to the url, you can instead use the general “List records” endpoint with the filterByFormula parameter to select the desired record, and then you can use the fields parameter to specify the fields. filterByFormula takes an Airtable formula, which in this case would be something like RECORD_ID()='recXXXXXXXXX' ​. Then you can use the fields param with field IDs, like so: ​fields[]=fldXXXXXXX&fields[]=fldXXXXXXX ​. You can use this site to generate (and encode) the proper URL for your request, and you can read more about these params in the “List records” section of your API documentation.

They also confirmed that the API only returns fields keyed by field name, not by field ID. I was able to workaround this by essentially passing the field names dynamically into my code from an AT Automation and then using that as my “map” to call and read the fields from.