How can I upload data to ThingSpeak with a custom timestamp instead of using the server’s current time?

I am currently using the ThingSpeak API to upload bat detection data from my project. I am trying to set the created_at timestamp to match the date and time captured from the image filenames. However, despite sending the created_at field in ISO 8601 format (YYYY-MM-DDTHH:MM:SSZ) via JSON in a POST request, ThingSpeak still records the current upload time instead of the provided timestamp.
Could you please clarify the correct way to send a custom timestamp so that ThingSpeak uses it instead of the current server time? Any guidance or examples would be greatly appreciated.

4 Comments

Bat data! A new data type for us I think. Sounds awesome.
Can you share the complete format of the request you are using now, and perhaps the channel ID?
The doc for write data has an example in the section in the expander "Write JSON encoded entry" You can pretty easiely turn that into a GET request if you prefer that. The parameter look like this: &created_at=2025-04-23 21:36:20 +0200 You may have to url encode it depending on the client you are using. then when you read .
Thank you for your response.
Currently, I am sending data to ThingSpeak using a POST request in JSON format like this:
location, date_str, month = extract_metadata(file.filename)
# Convert date string to ThingSpeak timestamp
from datetime import datetime
try:
date_obj = datetime.strptime(date_str, "%Y-%m-%d_%H-%M")
except ValueError:
date_obj = datetime.utcnow()
payload = {
"api_key": THINGSPEAK_API_KEY,
"field1": count, # Bat count
"field2": location, # Location
"created_at": date_obj.strftime("%Y-%m-%dT%H:%M:%SZ") #Custom timestamp from filename
}
The created_at field is populated using the timestamp extracted from the image filename or folder name which was collected previously. I want to make sure this timestamp accurately reflects the time the image was captured, not the time of upload.
Here are some example folder names:
  • 20250120_TolgaScrub_M3T_8am_30m
  • January_20250113_Gordonvale_M3T_6am_20m_Ortho
  • PilotStudy_MonashSt_20240918_M3T_Flight2
And example image files:
  • PilotStudy_MonashSt_20240918_M3T_Flight2_tile_1_7.png
Would you recommend switching to a GET request format for this data, like so:
If I decide to use the GET request, should I URL encode the created_at parameter (e.g., replacing spaces with %20)?
I want to ensure that the created_at timestamp is unique for each entry and accurately reflects the time from the image's metadata. Additionally, I would like to verify that the date format used in the request will work smoothly with ThingSpeak.
For reference, my ThingSpeak Channel ID is 3142218.
I suspect your http library takes care of the url encoding so I suggest wating to check on that till later.
The time format you are using seems good, but its not clear from the code snippet what happens if there are no seconds or minutes in the folder name.
Thingspeak still records the time you wrote the data (I think its updated at), but also uses created_at for your plots. One possibility is confusion due to times. Thingspeak stores data in UTC, but plots in the time zone that your web browser is set at. I looked at your channel data though, and I dont see evidence of this problem with the data in there currently.
I used POSTMAN to create some test datapoints and ensure it works.
You can also use your web browser address field to test, but then you need to use the GET requests.
This format worked for me
or here is the format from the doc page.
POST api.thingspeak.com/update.json
Content-Type: application/json
{
"api_key": "XXXXXXXXXXXXXXXX"
"created_at": "2018-04-23 21:36:20 +0200",
"field1": "John Johnson",
"field3": 56,
"field4": 555,
"field5": 444,
"latitude": "",
"longitude": "",
"status": "Please check in!"
}
You can try outputting the POST you are using to the serial monitor to ensure its fromatted correctly.
Thanks for the help! You were right, ThingSpeak was saving the timestamp correctly, but since my image filenames included old capture dates (like 2024), those points didn’t appear on the default chart view, which only shows recent data. Everything’s uploading fine now!
Currently, if the filename lacks a time component, my code defaults to datetime.utcnow().

Sign in to comment.

Answers (0)

Communities

More Answers in the  ThingSpeak Community

Categories

Products

Tags

Asked:

Doa
on 5 Nov 2025

Edited:

Doa
on 8 Nov 2025

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!