I'm playing around with the v3 API and trying to demo the concept of scheduling emails and then cancelling them. Here is what I did:
POST https://api.sendgrid.com/v3/mail/batch
and got batch a batch IDPOST https://api.sendgrid.com/v3/mail/send
and included that batch ID as the batch_id
parameter and put in a future send_at
timePOST https://api.sendgrid.com/v3/user/scheduled_sends/:batch_id
However the latter call fails as 404 Not Found with "message": "batch id not found"
. In fact it would seem that however many batch IDs I create, attempting to update them always yields this not-found message. The result is, the scheduled send cannot be cancelled, and the email sends at the appointed time. I should add that attempting to GET /v3/mail/batch/{batch_id}
returns an empty array []
.
Am I doing something wrong here?? Is this a limitation of the free account perhaps?
EDIT: I'm going to add some raw details to show what I am doing. I am doing these in Postman but I will export in cURL syntax to demonstrate.
First I create a batch:
curl --location --request POST 'https://api.sendgrid.com/v3/mail/batch' \
--header 'Accept: application/json' \
--header 'Authorization: Bearer <token redacted>' \
--data-raw ''
Response: {"batch_id":"OWU0NzgxYzUtMjkzZS0xMWVkLTg5NDAtYWUyMDAwNjVjZGU0LTZiODk2MDliZA"}
So now the next thing I want to try is to verify that batch ID:
curl --location --request GET 'https://api.sendgrid.com/v3/user/scheduled_sends/OWU0NzgxYzUtMjkzZS0xMWVkLTg5NDAtYWUyMDAwNjVjZGU0LTZiODk2MDliZA' \
--header 'Accept: application/json' \
--header 'Authorization: Bearer <token redacted>'
The response is, oddly, a 200 OK
with just []
which doesn't seem right does it? I created a batch and it has an ID, so why can't I verify its existence?
Documentation here states: https://docs.sendgrid.com/api-reference/cancel-scheduled-sends/validate-batch-id
When you pass a valid
batch_id
to this endpoint, it will return a200
status code and the batch ID itself.If you pass an invalid
batch_id
to the endpoint, you will receive a 400 level status code and an error message.A
batch_id
does not need to be assigned to a scheduled send to be considered valid. A successful response means only that the batch_id has been created, but it does not indicate that it has been associated with a send.
Interestingly if I put any arbitrary string in that URL instead of a batch ID, I also get a 200 OK with empty array. I cannot even reproduce what the document is saying about receiving a 400 error for an invalid ID.
However if I take it on faith that the batch WAS created, I would go ahead and try to send an email with it:
curl --location --request POST 'https://api.sendgrid.com/v3/mail/send' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <token redacted>' \
--data-raw '{
"batch_id": "OWU0NzgxYzUtMjkzZS0xMWVkLTg5NDAtYWUyMDAwNjVjZGU0LTZiODk2MDliZA",
"send_at": 1661969713,
"personalizations": [{
"to": [{
"email": "thatemail@mycompany.com",
"name": "John Doe"
}
]
}],
"from": {
"email": "myemail@mycompany.com",
"name": "Jane Doe"
},
"reply_to": {
"email": "customer_service@example.com",
"name": "Example Customer Service Team"
},
"subject": "Example Email 6",
"content": [{
"type": "text/html",
"value": "<p>Test email!</p><p>%open-track%</p>"
}
],
"custom_args":{
"sf-id": "some-arbitrary-id6",
"sf-org-id": "some-arbitrary-org-id"
},
"mail_settings": {
"sandbox_mode": {
"enable": false
}
},
"tracking_settings": {
"click_tracking": {
"enable": true,
"enable_text": false
},
"open_tracking": {
"enable": true,
"substitution_tag": "%open-track%"
},
"subscription_tracking": {
"enable": false
}
}
}
'
At the time of writing that timestamp is for 3h from now, resolving at 2:15PM August 31st Eastern Time. I send that call and get 202 Accepted
.
Then, finally, I attempt to pause the batch.
curl --location --request PATCH 'https://api.sendgrid.com/v3/user/scheduled_sends/OWU0NzgxYzUtMjkzZS0xMWVkLTg5NDAtYWUyMDAwNjVjZGU0LTZiODk2MDliZA' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <token redacted>' \
--data-raw '{"status": "pause"}'
My response is a 404 NOT FOUND
with:
{
"errors": [
{
"field": null,
"message": "batch id not found"
}
]
}
So... what is going on here???
So a few things:
POST /v3/user/scheduled_sends/
with batch_id
in the request body. I was trying PATCH
. Strange behaviour here as the batch ID already exists, but OK.GET /v3/mail/batch/{batch_id}
API changed for me. I am no longer able to reproduce getting back an empty array. Every response is either a success with the batch ID or a fail.I don't know why these behaviours changed, but they did. There may be some quirk in which fresh accounts that have never paused/cancelled a batch simply do not have a functional "validate batch" call. Now that I have done a successful pause for the first time, the behaviour of GET /v3/mail/batch/{batch_id}
finally matches the documentation.