Send one message with a template's live version
# REPUTECAST_API_KEY: an API key (rc_live_…) with transactional:send.# Replace reputecast.example.com with your public URL and your-workspace with your workspace slug.curl --request POST \ --url https://reputecast.example.com/api/v1/workspaces/your-workspace/transactional/messages \ --header "Authorization: Bearer $REPUTECAST_API_KEY" \ --header 'Content-Type: application/json' \ --header 'Idempotency-Key: password-reset-8f14e45f' \ --data '{ "template": "password-reset", "to": { "email": "[email protected]", "name": "Sam Rivera" }, "data": { "first_name": "Sam", "reset_url": "https://app.example.com/reset/8f14e45f", "expires_in": "30 minutes" }, "tags": ["password-reset"] }'// REPUTECAST_API_KEY: an API key (rc_live_…) with transactional:send.// Replace reputecast.example.com with your public URL and your-workspace with your workspace slug.const response = await fetch( 'https://reputecast.example.com/api/v1/workspaces/your-workspace/transactional/messages', { method: 'POST', headers: { Authorization: `Bearer ${process.env.REPUTECAST_API_KEY}`, 'Content-Type': 'application/json', // A retry with the same key within 24 hours never sends twice. 'Idempotency-Key': 'password-reset-8f14e45f', }, body: JSON.stringify({ template: 'password-reset', data: { first_name: 'Sam', reset_url: 'https://app.example.com/reset/8f14e45f', expires_in: '30 minutes', }, tags: ['password-reset'], }), },)const result = await response.json()if (!response.ok) throw new Error(`${response.status} ${result.code}: ${result.detail}`)console.log(result.id, result.status) // status: queued// REPUTECAST_API_KEY: an API key (rc_live_…) with transactional:send.// Replace reputecast.example.com with your public URL and your-workspace with your workspace slug.package main
import ( "bytes" "encoding/json" "fmt" "log" "net/http" "os")
func main() { body, err := json.Marshal(map[string]any{ "template": "password-reset", "data": map[string]string{ "first_name": "Sam", "reset_url": "https://app.example.com/reset/8f14e45f", "expires_in": "30 minutes", }, "tags": []string{"password-reset"}, }) if err != nil { log.Fatal(err) } req, err := http.NewRequest(http.MethodPost, "https://reputecast.example.com/api/v1/workspaces/your-workspace/transactional/messages", bytes.NewReader(body)) if err != nil { log.Fatal(err) } req.Header.Set("Authorization", "Bearer "+os.Getenv("REPUTECAST_API_KEY")) req.Header.Set("Content-Type", "application/json") // A retry with the same key within 24 hours never sends twice. req.Header.Set("Idempotency-Key", "password-reset-8f14e45f")
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
var result struct { ID string `json:"id"` Status string `json:"status"` Code string `json:"code"` Detail string `json:"detail"` } if err := json.NewDecoder(resp.Body).Decode(&result); err != nil { log.Fatal(err) } if resp.StatusCode >= 300 { log.Fatalf("%d %s: %s", resp.StatusCode, result.Code, result.Detail) } fmt.Println(result.ID, result.Status) // status: queued}# REPUTECAST_API_KEY: an API key (rc_live_…) with transactional:send.# Replace reputecast.example.com with your public URL and your-workspace with your workspace slug.import os
import requests
response = requests.post( "https://reputecast.example.com/api/v1/workspaces/your-workspace/transactional/messages", headers={ "Authorization": f"Bearer {os.environ['REPUTECAST_API_KEY']}", # A retry with the same key within 24 hours never sends twice. "Idempotency-Key": "password-reset-8f14e45f", }, json={ "template": "password-reset", "data": { "first_name": "Sam", "reset_url": "https://app.example.com/reset/8f14e45f", "expires_in": "30 minutes", }, "tags": ["password-reset"], }, timeout=10,)result = response.json()if not response.ok: raise RuntimeError(f"{response.status_code} {result.get('code')}: {result.get('detail')}")print(result["id"], result["status"]) # status: queued<?php// REPUTECAST_API_KEY: an API key (rc_live_…) with transactional:send.// Replace reputecast.example.com with your public URL and your-workspace with your workspace slug.$payload = [ 'template' => 'password-reset', 'data' => [ 'first_name' => 'Sam', 'reset_url' => 'https://app.example.com/reset/8f14e45f', 'expires_in' => '30 minutes', ], 'tags' => ['password-reset'],];
$ch = curl_init('https://reputecast.example.com/api/v1/workspaces/your-workspace/transactional/messages');curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ 'Authorization: Bearer ' . getenv('REPUTECAST_API_KEY'), 'Content-Type: application/json', // A retry with the same key within 24 hours never sends twice. 'Idempotency-Key: password-reset-8f14e45f', ], CURLOPT_POSTFIELDS => json_encode($payload, JSON_THROW_ON_ERROR),]);$body = curl_exec($ch);if ($body === false) { throw new RuntimeException(curl_error($ch));}$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);$result = json_decode($body, true, flags: JSON_THROW_ON_ERROR);if ($status >= 300) { throw new RuntimeException("{$status} {$result['code']}: {$result['detail']}");}echo $result['id'], ' ', $result['status'], PHP_EOL; // status: queuedPermission: transactional:send (sensitive)
Answers 202 with the message ID and status queued (scheduled with send_at). Errors are RFC 9457 problems whose detail says what to fix: template_not_found, template_not_published, missing_variables (listed in missing), invalid_recipient, recipient_suppressed (with the reason and date), sender_not_verified, attachments_too_large (naming the route’s provider limit), rate_limited (with Retry-After), no_healthy_route. Send an Idempotency-Key header: a retry with the same key within 24 hours gets the first answer and sends nothing. A test-mode key delivers only to the workspace’s members and its allowed test addresses.
Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Path Parameters
Section titled “Path Parameters”Workspace slug
Workspace slug
Header Parameters
Section titled “Header Parameters”A retry with the same key within 24 hours never sends twice
A retry with the same key within 24 hours never sends twice
Request Bodyrequired
Section titled “Request Bodyrequired”object
object
The file, base64-encoded
Makes it an inline image the HTML references as cid:<content_id>
Guessed from the file name when omitted
object
object
The template’s variables
object
A verified Transactional sender, as an address or “Name
”; the template’s sender when omittedThe language version to send; the linked contact’s language, then the fallback, when omitted
object
Overrides the template’s preheader (Liquid)
Send later, up to 72 hours ahead
Overrides the template’s subject (Liquid)
Returned with every webhook event of the message
The template’s ID
object
Responses
Section titled “Responses”Accepted
object
Not_delivered: a test-mode key’s message to an address that isn’t allowed
Sent with a test-mode key
Example
{ "id": "0192f1c4-7b2e-7c51-9d0a-3f5e8b1a2c44", "status": "queued"}default
Section titled “default”Error
object
Stable error code, e.g. permission_denied
A human-readable explanation specific to this occurrence of the problem.
Optional list of individual error details
object
Where the error occurred, e.g. ‘body.items[3].tags’ or ‘path.thing-id’
Error message text
The value at the given location
Members who hold the missing permission
A URI reference that identifies the specific occurrence of the problem.
object
The missing permission key
HTTP status code
A short, human-readable summary of the problem type. This value should not change between occurrences of the error.
A URI reference to human-readable documentation for the error.
Example
{ "detail": "Property foo is required but is missing.", "instance": "https://example.com/error-log/abc123", "status": 400, "title": "Bad Request", "type": "about:blank"}