I need help making a census app and pet tracker

Hi @codeswept and all the others,

thanks for the hint pointing towards AIforEarth. I got my API key but I am still not able to get a species analysis. This is what I do so far:

  • get a picture with my camera
  • upload that picture to cloudinary. Cloudinary gives me a mediaURL.
  • connect via Web_API to AIforEarth with POST and giving the mediaURL as body. Is that correct? The documentation of AI for Earth is totally useless. I always get “500 - internal server error…”.

Has anybody had success in using AIforEarth, and if so, how?

I guess that the body of the POST message should contain the picture in base64 encoded, but in thunkable or cloudinary there is no base64 encoder.

@Michael_Rogulla I’m glad to hear someone else is trying this!

I got exactly as far as you did. I read through dozens of documentation pages and tried dozens of ways of POSTing an image url but I either get a 500 internal server error or I get an error about an unsupported media type. I even thought to try base64 but didn’t get anywhere with that (only a half-hearted try).

I’m really wondering if it can handle external urls at all. AI for Earth has a “blob” image server and it may be that the tool only works on images stored there. I sure hope not, though.

I haven’t even managed to add the API in my app. Still trying… Where can I get the API key from? I haven’t been able to understand anything from the documents you shared @tatiang.

As a teacher, I requested an API by clicking the “Request an API key” link at https://www.microsoft.com/en-us/ai/ai-for-earth-tech-resources.

But even after several hours of trying, I wasn’t able to get the Web API call to work.

On the other hand, it’s really easy to get the built-in image recognition to work. It’s just not all that reliable or detailed (“dog” vs. “golden retriever”).


Hi @codeswept , @tatiang and the others,

her is what I did:

  • I requested an API key and got a link with login information for an AI4earth server
  • there I could find my credentials under my user settings. It consists of two keys, a primary key and a secondary key. I could find no information what’s the difference.
  • then I made a simple app in ThunkableX with a camera, a mediaDB (=Cloudinary) and a Web_API component
  • you need to configure the Web_API component in designer mode like this:
    – the Web_API URL should look like this: https://aiforearth.azure-api.net/species-classification/v2.0/predict?topK=3&predictMode=classifyAndDetect
    – your API key goes here: enter " Ocp-Apim-Subscription-Key in Headers property, enter your primary key in “Value” and click on “Add”.
  • the mediaDB must be configured with CloudName, APIkey and APIsecret from Cloudinary.
    – I am not sure but I hope to find a way that cloudinary delivers a base64 encoded image, otherwise we all need a Web-Service that converts a picture (from the cloudinary “mediaURL”) into a base64 encoded string. I think that’s the missing part in using AI4earth.

Here is how my blocks look like. I alway get “500 - internal server error blablabla…”. Maybe all will go well with base64 encoded pictures. I am also not sure how to enter the data into the body, maybe I have to use an object, or a JSON-String?

1 Like

That seems to be a lot of work… thanks for sharing that @Michael_Rogulla! I’m still trying to figure out how it works.

@drted explains here that you have to use object blocks with the Web API “Body” block.

1 Like

I am trying to add a ‘search’ option so users can only view reports of certain species, like if they search ‘cat’ then reports from ‘cat’ are supposed to come from Airtable. This is my code, that’s not working:

Where have I gone wrong?
Thanks in advance!

Are the values in your “Recognizer tags” column Airtable row IDs? The way you have it set up is a little circular… it would help if you could show what your Airtable column headers and (a little bit of) data look like.


I have filled that in on Airtable, just for placeholders when there are no actual reports yet.

I have created a separate DataViewer List and hidden the first one for showing filtered reports.

When you loop through “for each item j in list,” you’re looping through the column values (#dog #blackandwhite, then #dog, then #cat, then #cow).

But your “if” block checks to see if the value in the “Recognizer tags” column for an Airtable row with “j” as the row ID is equal to the user’s input. Your Airtable is never going to have a row with row ID “#dog” for example. Row IDs are long strings of characters that look sort of like d4590ui18572m3.

To fix this part, replace the first “get value” block with just the “j” variable block. Because “j” already contains #dog #blackandwhite (for the first row, for example). You just need to see if “j” contains the text input.

Thank you. Very helpful

Sadly, it’s not appearing:

This is what it looks like after searching:

The value of the variable “j” is just the string “#dog” or whatever is in the Recognizer tags column in Airtable. You’re still using j as if it’s a row id. It’s not.

It’s like if I told you, can you go outside and grab “#dog” lemons from the tree? You’d have no idea how many to get. Or take the "#dog"th person in line and give them a prize. Which one? It’s not a row id or a number that is useful in this way.

The first step is to see if your IF condition is working. I would change the value of a label to “found” or something like that right below the “if” block. Since it’s in a loop, maybe add a vibrate block so you can tell if it works when tested on a mobile device. If you get confirmation that the IF condition is set up correctly, then move to figuring out how to display the related information.

You’ll need to know which row contained the tag inputted by the user. So you’ll probably want a counter variable that increments by one each time the “for each item j in list” loop iterates. That way, when you find a “j” that contains the tag, you’ll know what number row (in Airtable) it’s in.

Here’s a video by @Darren that demonstrates how to search and display data from Airtable:

Also, this set of blocks:

Thanks so much! Will change the ‘j’.

I think I got what the problem was. I think the code worked correctly, but I didn’t delete the rows that weren’t the search input. I created another table in Airtable to fix that. Still trying to see what will work. I stopped using the recognizer tags get list of values, and changed it to IDs.