curl --request POST \
--url https://api.talqing.com/v1/email/batches/{batch_id}/sends \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"from_email": "<string>",
"from_name": "<string>",
"recipient_ids": [
"3c90c3cc-0d44-4b50-8888-8dd25736052a"
],
"reply_to": "<string>",
"send_attempts": 123,
"send_daily_cap": {
"kind": "fixed",
"limit": 2
},
"send_gap_seconds": 123,
"send_retry_after_minutes": 123,
"start_at": "2023-11-07T05:31:56Z",
"timezone": "<string>",
"window": {
"end": "<string>",
"start": "<string>",
"days": [
1,
2,
3,
4,
5,
6,
7
]
}
}
'import requests
url = "https://api.talqing.com/v1/email/batches/{batch_id}/sends"
payload = {
"from_email": "<string>",
"from_name": "<string>",
"recipient_ids": ["3c90c3cc-0d44-4b50-8888-8dd25736052a"],
"reply_to": "<string>",
"send_attempts": 123,
"send_daily_cap": {
"kind": "fixed",
"limit": 2
},
"send_gap_seconds": 123,
"send_retry_after_minutes": 123,
"start_at": "2023-11-07T05:31:56Z",
"timezone": "<string>",
"window": {
"end": "<string>",
"start": "<string>",
"days": [1, 2, 3, 4, 5, 6, 7]
}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
from_email: '<string>',
from_name: '<string>',
recipient_ids: ['3c90c3cc-0d44-4b50-8888-8dd25736052a'],
reply_to: '<string>',
send_attempts: 123,
send_daily_cap: {kind: 'fixed', limit: 2},
send_gap_seconds: 123,
send_retry_after_minutes: 123,
start_at: '2023-11-07T05:31:56Z',
timezone: '<string>',
window: {end: '<string>', start: '<string>', days: [1, 2, 3, 4, 5, 6, 7]}
})
};
fetch('https://api.talqing.com/v1/email/batches/{batch_id}/sends', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.talqing.com/v1/email/batches/{batch_id}/sends",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'from_email' => '<string>',
'from_name' => '<string>',
'recipient_ids' => [
'3c90c3cc-0d44-4b50-8888-8dd25736052a'
],
'reply_to' => '<string>',
'send_attempts' => 123,
'send_daily_cap' => [
'kind' => 'fixed',
'limit' => 2
],
'send_gap_seconds' => 123,
'send_retry_after_minutes' => 123,
'start_at' => '2023-11-07T05:31:56Z',
'timezone' => '<string>',
'window' => [
'end' => '<string>',
'start' => '<string>',
'days' => [
1,
2,
3,
4,
5,
6,
7
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.talqing.com/v1/email/batches/{batch_id}/sends"
payload := strings.NewReader("{\n \"from_email\": \"<string>\",\n \"from_name\": \"<string>\",\n \"recipient_ids\": [\n \"3c90c3cc-0d44-4b50-8888-8dd25736052a\"\n ],\n \"reply_to\": \"<string>\",\n \"send_attempts\": 123,\n \"send_daily_cap\": {\n \"kind\": \"fixed\",\n \"limit\": 2\n },\n \"send_gap_seconds\": 123,\n \"send_retry_after_minutes\": 123,\n \"start_at\": \"2023-11-07T05:31:56Z\",\n \"timezone\": \"<string>\",\n \"window\": {\n \"end\": \"<string>\",\n \"start\": \"<string>\",\n \"days\": [\n 1,\n 2,\n 3,\n 4,\n 5,\n 6,\n 7\n ]\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.talqing.com/v1/email/batches/{batch_id}/sends")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"from_email\": \"<string>\",\n \"from_name\": \"<string>\",\n \"recipient_ids\": [\n \"3c90c3cc-0d44-4b50-8888-8dd25736052a\"\n ],\n \"reply_to\": \"<string>\",\n \"send_attempts\": 123,\n \"send_daily_cap\": {\n \"kind\": \"fixed\",\n \"limit\": 2\n },\n \"send_gap_seconds\": 123,\n \"send_retry_after_minutes\": 123,\n \"start_at\": \"2023-11-07T05:31:56Z\",\n \"timezone\": \"<string>\",\n \"window\": {\n \"end\": \"<string>\",\n \"start\": \"<string>\",\n \"days\": [\n 1,\n 2,\n 3,\n 4,\n 5,\n 6,\n 7\n ]\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.talqing.com/v1/email/batches/{batch_id}/sends")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"from_email\": \"<string>\",\n \"from_name\": \"<string>\",\n \"recipient_ids\": [\n \"3c90c3cc-0d44-4b50-8888-8dd25736052a\"\n ],\n \"reply_to\": \"<string>\",\n \"send_attempts\": 123,\n \"send_daily_cap\": {\n \"kind\": \"fixed\",\n \"limit\": 2\n },\n \"send_gap_seconds\": 123,\n \"send_retry_after_minutes\": 123,\n \"start_at\": \"2023-11-07T05:31:56Z\",\n \"timezone\": \"<string>\",\n \"window\": {\n \"end\": \"<string>\",\n \"start\": \"<string>\",\n \"days\": [\n 1,\n 2,\n 3,\n 4,\n 5,\n 6,\n 7\n ]\n }\n}"
response = http.request(request)
puts response.read_body{
"rejected": [
{
"reason": "<string>",
"recipient_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"row_number": 123
}
],
"send": {
"batch_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"counts": {
"drafting": 123,
"queued": 123,
"send_failed": 123,
"sending": 123,
"sent": 123,
"skipped": 123,
"total": 123
},
"created_at": "2023-11-07T05:31:56Z",
"failure_reason": "<string>",
"finished_at": "2023-11-07T05:31:56Z",
"from_email": "<string>",
"from_name": "<string>",
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"next_send_at": "2023-11-07T05:31:56Z",
"next_send_reason": "start",
"reply_to": "<string>",
"scope": "all",
"send_attempts": 123,
"send_daily_cap": {
"kind": "fixed",
"limit": 2
},
"send_daily_cap_today": 123,
"send_gap_seconds": 123,
"send_retry_after_minutes": 123,
"start_at": "2023-11-07T05:31:56Z",
"started_at": "2023-11-07T05:31:56Z",
"status": "scheduled",
"timezone": "<string>",
"window": {
"end": "<string>",
"start": "<string>",
"days": [
1,
2,
3,
4,
5,
6,
7
]
}
}
}{
"detail": {
"errors": [
"<string>"
],
"message": "<string>",
"code": "<string>"
}
}{
"detail": {
"errors": [
"<string>"
],
"message": "<string>",
"code": "<string>"
}
}{
"detail": {
"errors": [
"<string>"
],
"message": "<string>",
"code": "<string>"
}
}{
"detail": {
"errors": [
"<string>"
],
"message": "<string>",
"code": "<string>"
}
}{
"detail": {
"errors": [
"<string>"
],
"message": "<string>",
"code": "<string>"
}
}{
"detail": {
"errors": [
"<string>"
],
"message": "<string>",
"code": "<string>"
}
}{
"detail": {
"errors": [
"<string>"
],
"message": "<string>",
"code": "<string>"
}
}Create Email Send
Send rows. This mails real people and cannot be undone.
scope: "selected" sends recipient_ids; a row that cannot be sent comes
back in rejected and stays a draft. scope: "all" sends every row as it
finishes drafting — including drafts nobody has read — and waits while
drafting runs. It cannot be live beside another send of the batch (409).
start_at schedules it, window holds it to business hours, and
send_gap_seconds and send_daily_cap (a fixed limit or a ramp) pace the
whole batch. Everything
omitted comes from the batch. Cancelling it leaves the unsent rows as drafts.
curl --request POST \
--url https://api.talqing.com/v1/email/batches/{batch_id}/sends \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"from_email": "<string>",
"from_name": "<string>",
"recipient_ids": [
"3c90c3cc-0d44-4b50-8888-8dd25736052a"
],
"reply_to": "<string>",
"send_attempts": 123,
"send_daily_cap": {
"kind": "fixed",
"limit": 2
},
"send_gap_seconds": 123,
"send_retry_after_minutes": 123,
"start_at": "2023-11-07T05:31:56Z",
"timezone": "<string>",
"window": {
"end": "<string>",
"start": "<string>",
"days": [
1,
2,
3,
4,
5,
6,
7
]
}
}
'import requests
url = "https://api.talqing.com/v1/email/batches/{batch_id}/sends"
payload = {
"from_email": "<string>",
"from_name": "<string>",
"recipient_ids": ["3c90c3cc-0d44-4b50-8888-8dd25736052a"],
"reply_to": "<string>",
"send_attempts": 123,
"send_daily_cap": {
"kind": "fixed",
"limit": 2
},
"send_gap_seconds": 123,
"send_retry_after_minutes": 123,
"start_at": "2023-11-07T05:31:56Z",
"timezone": "<string>",
"window": {
"end": "<string>",
"start": "<string>",
"days": [1, 2, 3, 4, 5, 6, 7]
}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
from_email: '<string>',
from_name: '<string>',
recipient_ids: ['3c90c3cc-0d44-4b50-8888-8dd25736052a'],
reply_to: '<string>',
send_attempts: 123,
send_daily_cap: {kind: 'fixed', limit: 2},
send_gap_seconds: 123,
send_retry_after_minutes: 123,
start_at: '2023-11-07T05:31:56Z',
timezone: '<string>',
window: {end: '<string>', start: '<string>', days: [1, 2, 3, 4, 5, 6, 7]}
})
};
fetch('https://api.talqing.com/v1/email/batches/{batch_id}/sends', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.talqing.com/v1/email/batches/{batch_id}/sends",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'from_email' => '<string>',
'from_name' => '<string>',
'recipient_ids' => [
'3c90c3cc-0d44-4b50-8888-8dd25736052a'
],
'reply_to' => '<string>',
'send_attempts' => 123,
'send_daily_cap' => [
'kind' => 'fixed',
'limit' => 2
],
'send_gap_seconds' => 123,
'send_retry_after_minutes' => 123,
'start_at' => '2023-11-07T05:31:56Z',
'timezone' => '<string>',
'window' => [
'end' => '<string>',
'start' => '<string>',
'days' => [
1,
2,
3,
4,
5,
6,
7
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.talqing.com/v1/email/batches/{batch_id}/sends"
payload := strings.NewReader("{\n \"from_email\": \"<string>\",\n \"from_name\": \"<string>\",\n \"recipient_ids\": [\n \"3c90c3cc-0d44-4b50-8888-8dd25736052a\"\n ],\n \"reply_to\": \"<string>\",\n \"send_attempts\": 123,\n \"send_daily_cap\": {\n \"kind\": \"fixed\",\n \"limit\": 2\n },\n \"send_gap_seconds\": 123,\n \"send_retry_after_minutes\": 123,\n \"start_at\": \"2023-11-07T05:31:56Z\",\n \"timezone\": \"<string>\",\n \"window\": {\n \"end\": \"<string>\",\n \"start\": \"<string>\",\n \"days\": [\n 1,\n 2,\n 3,\n 4,\n 5,\n 6,\n 7\n ]\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.talqing.com/v1/email/batches/{batch_id}/sends")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"from_email\": \"<string>\",\n \"from_name\": \"<string>\",\n \"recipient_ids\": [\n \"3c90c3cc-0d44-4b50-8888-8dd25736052a\"\n ],\n \"reply_to\": \"<string>\",\n \"send_attempts\": 123,\n \"send_daily_cap\": {\n \"kind\": \"fixed\",\n \"limit\": 2\n },\n \"send_gap_seconds\": 123,\n \"send_retry_after_minutes\": 123,\n \"start_at\": \"2023-11-07T05:31:56Z\",\n \"timezone\": \"<string>\",\n \"window\": {\n \"end\": \"<string>\",\n \"start\": \"<string>\",\n \"days\": [\n 1,\n 2,\n 3,\n 4,\n 5,\n 6,\n 7\n ]\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.talqing.com/v1/email/batches/{batch_id}/sends")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"from_email\": \"<string>\",\n \"from_name\": \"<string>\",\n \"recipient_ids\": [\n \"3c90c3cc-0d44-4b50-8888-8dd25736052a\"\n ],\n \"reply_to\": \"<string>\",\n \"send_attempts\": 123,\n \"send_daily_cap\": {\n \"kind\": \"fixed\",\n \"limit\": 2\n },\n \"send_gap_seconds\": 123,\n \"send_retry_after_minutes\": 123,\n \"start_at\": \"2023-11-07T05:31:56Z\",\n \"timezone\": \"<string>\",\n \"window\": {\n \"end\": \"<string>\",\n \"start\": \"<string>\",\n \"days\": [\n 1,\n 2,\n 3,\n 4,\n 5,\n 6,\n 7\n ]\n }\n}"
response = http.request(request)
puts response.read_body{
"rejected": [
{
"reason": "<string>",
"recipient_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"row_number": 123
}
],
"send": {
"batch_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"counts": {
"drafting": 123,
"queued": 123,
"send_failed": 123,
"sending": 123,
"sent": 123,
"skipped": 123,
"total": 123
},
"created_at": "2023-11-07T05:31:56Z",
"failure_reason": "<string>",
"finished_at": "2023-11-07T05:31:56Z",
"from_email": "<string>",
"from_name": "<string>",
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"next_send_at": "2023-11-07T05:31:56Z",
"next_send_reason": "start",
"reply_to": "<string>",
"scope": "all",
"send_attempts": 123,
"send_daily_cap": {
"kind": "fixed",
"limit": 2
},
"send_daily_cap_today": 123,
"send_gap_seconds": 123,
"send_retry_after_minutes": 123,
"start_at": "2023-11-07T05:31:56Z",
"started_at": "2023-11-07T05:31:56Z",
"status": "scheduled",
"timezone": "<string>",
"window": {
"end": "<string>",
"start": "<string>",
"days": [
1,
2,
3,
4,
5,
6,
7
]
}
}
}{
"detail": {
"errors": [
"<string>"
],
"message": "<string>",
"code": "<string>"
}
}{
"detail": {
"errors": [
"<string>"
],
"message": "<string>",
"code": "<string>"
}
}{
"detail": {
"errors": [
"<string>"
],
"message": "<string>",
"code": "<string>"
}
}{
"detail": {
"errors": [
"<string>"
],
"message": "<string>",
"code": "<string>"
}
}{
"detail": {
"errors": [
"<string>"
],
"message": "<string>",
"code": "<string>"
}
}{
"detail": {
"errors": [
"<string>"
],
"message": "<string>",
"code": "<string>"
}
}{
"detail": {
"errors": [
"<string>"
],
"message": "<string>",
"code": "<string>"
}
}Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Path Parameters
Body
Send these rows. This is the call that mails real people.
scope: "selected" sends exactly recipient_ids. scope: "all" is a
standing send: every row of the batch as it reaches draft, including rows
not drafted yet — so it mails drafts nobody has read. Everything else
defaults to the batch's own setting; window and send_daily_cap accept
an explicit null to mean "no window" and "uncapped" rather than
"inherit", so the service reads model_fields_set.
The sender applies to THIS send alone and never writes back to the batch.
selected sends recipient_ids; all sends every row as it is drafted.
all, selected 20010000The same limit every day.
- FixedDailyCap
- RampDailyCap
Show child attributes
Show child attributes
The hours a list may run in, on the list's own clock.
Shared rather than duplicated, for the same reason window_state is: a
call batch and an email send run store the same three values under the same
names and must not each get their own copy of the rules. The field that
carries one is named for what it gates — calling_window on a campaign,
window on an email batch and its runs.
A window that crosses midnight (21:00-06:00) is valid and means
exactly what an evening consumer-calling window means: the day check applies
to the start side, so 21:00-06:00 on days: [5] runs Friday
21:00 through Saturday 06:00.
Show child attributes
Show child attributes
Response
Successful Response
The send that was created, and every row that did not go into it.
Two halves rather than one, because they answer different questions and a caller needs both: what is now scheduled to go out, and which rows it refused and why. If NOTHING in the selection could be sent there is no send to describe, so that case is a 400 naming the reasons instead.