curl --request POST \
--url https://{companyName}.api.joinluminous.com/external/api/v1/invoices/{invoiceId}/send-email \
--header 'Authorization: Bearer <token>'import requests
url = "https://{companyName}.api.joinluminous.com/external/api/v1/invoices/{invoiceId}/send-email"
headers = {"Authorization": "Bearer <token>"}
response = requests.post(url, headers=headers)
print(response.text)const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};
fetch('https://{companyName}.api.joinluminous.com/external/api/v1/invoices/{invoiceId}/send-email', 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://{companyName}.api.joinluminous.com/external/api/v1/invoices/{invoiceId}/send-email",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://{companyName}.api.joinluminous.com/external/api/v1/invoices/{invoiceId}/send-email"
req, _ := http.NewRequest("POST", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://{companyName}.api.joinluminous.com/external/api/v1/invoices/{invoiceId}/send-email")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://{companyName}.api.joinluminous.com/external/api/v1/invoices/{invoiceId}/send-email")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"data": {
"invoice_id": 123,
"send_reference": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"status": "queued",
"accepted_at": "2023-11-07T05:31:56Z",
"recipients": [
{
"email": "jsmith@example.com",
"type": "to",
"status": "queued",
"error": "<string>"
}
]
}
}{
"message": "<string>"
}{
"message": "<string>"
}{
"message": "<string>"
}{
"message": "<string>"
}{
"message": "<string>"
}Email a Draft invoice
Email a Draft invoice to the contact(s) on file for its account. Mirrors the admin “send invoice” action: the invoice PDF is rendered from the tenant’s default template and the email is queued for delivery. The account’s sales reps are CC’d, exactly as the UI action does.
The endpoint accepts no request body — recipients are always the invoice’s contact(s) on file, and the template cannot be chosen per request.
Only invoices in Draft status can be emailed; any other status returns 422.
The reported status describes acceptance onto the send queue, not delivery —
knowing whether mail landed, bounced, or was opened is out of scope. send_reference
is an opaque handle echoed back and written to the invoice’s activity log so a send
can be correlated after the fact.
Requires the API token user to have the send-invoices permission
(invoices.send), granted to super-admin and admin roles only.
Idempotency: this endpoint has an irreversible side effect — once the customer
has the mail, no retry can unsend it — so it supports the optional Idempotency-Key
request header. Send the same key on a retry to replay the original response instead
of queueing a second email; replayed responses carry an Idempotent-Replay: true
header. Omitting the header passes straight through with no idempotency guard, so two
identical calls queue two emails (exactly as two clicks of the UI action would).
curl --request POST \
--url https://{companyName}.api.joinluminous.com/external/api/v1/invoices/{invoiceId}/send-email \
--header 'Authorization: Bearer <token>'import requests
url = "https://{companyName}.api.joinluminous.com/external/api/v1/invoices/{invoiceId}/send-email"
headers = {"Authorization": "Bearer <token>"}
response = requests.post(url, headers=headers)
print(response.text)const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};
fetch('https://{companyName}.api.joinluminous.com/external/api/v1/invoices/{invoiceId}/send-email', 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://{companyName}.api.joinluminous.com/external/api/v1/invoices/{invoiceId}/send-email",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://{companyName}.api.joinluminous.com/external/api/v1/invoices/{invoiceId}/send-email"
req, _ := http.NewRequest("POST", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://{companyName}.api.joinluminous.com/external/api/v1/invoices/{invoiceId}/send-email")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://{companyName}.api.joinluminous.com/external/api/v1/invoices/{invoiceId}/send-email")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"data": {
"invoice_id": 123,
"send_reference": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"status": "queued",
"accepted_at": "2023-11-07T05:31:56Z",
"recipients": [
{
"email": "jsmith@example.com",
"type": "to",
"status": "queued",
"error": "<string>"
}
]
}
}{
"message": "<string>"
}{
"message": "<string>"
}{
"message": "<string>"
}{
"message": "<string>"
}{
"message": "<string>"
}Authorizations
Authenticate using a bearer token. To create a token, navigate to /settings/api-tokens and click Create API Token.
Headers
Optional opt-in idempotency token. When supplied, a retry carrying the same key
replays the original stored response (with an Idempotent-Replay: true header)
instead of queueing another email. Omit it to disable the guard for this request.
Path Parameters
ID of the Draft invoice to email
Response
The email was queued for at least one recipient. A partial status means some
recipients were queued and some could not be; see the per-recipient recipients
array for detail.
Show child attributes
Show child attributes