Create a scoped key
Create a key in the workspace and environment that owns the sender. Store it in your secret manager.
Reference
Use a workspace API key to send mail, manage domains, and subscribe to delivery events. The dashboard is the operator control room; keys are the integration path.
Start here
Keep the API key on your server, choose the right environment, and make one idempotent request. Clover accepts the message before the delivery workers continue the lifecycle.
Create a key in the workspace and environment that owns the sender. Store it in your secret manager.
Use the base URL for that environment and include an Idempotency-Key with every mutation.
Use the returned message and request IDs, then follow delivery state and provider feedback in the dashboard or webhook stream.
Protect the boundary
Clover uses bearer API keys for server-to-server requests. The key is scoped to its workspace and environment; never put it in browser code, public examples, or client-side storage.
Create a key from the authenticated dashboard and give it only the permissions the integration needs.
Send the key as Authorization: Bearer CLOVER_API_KEY on every API request.
Proxy browser actions through your server. Rotate a key from the dashboard if it is ever exposed.
Authenticated request
curl "$CLOVER_API_URL/api/v1/platform/accounts/$ACCOUNT_ID/environments/$ENVIRONMENT_ID/messages" \
-H "Authorization: Bearer $CLOVER_API_KEY" \
-H "Content-Type: application/json" \
-H "X-Request-ID: req_example_0001" \
-H "Idempotency-Key: send-2026-0001"Choose the boundary
Do not bake an environment into application logic. Set CLOVER_API_URL per deployment and keep the same SDK configuration across local, staging, and production.
| Environment | Base URL | Use |
|---|---|---|
| Local | http://localhost:8080 | Disposable development services |
| Staging | https://api.staging.sendclover.com | Safe integration and acceptance checks |
| Production | Assigned production origin | Live delivery for your workspace |
CLOVER_API_URL · Use the origin only; append Clover API paths in the SDK or request client.
Retry safely
The Idempotency-Key header makes retries safe when a network timeout leaves the result unknown. Reuse the same key only for the same logical operation and payload.
A transactional send
POST /api/v1/platform/accounts/{account_id}/environments/{environment_id}/messages
Authorization: Bearer $CLOVER_API_KEY
X-Request-ID: req_example_0001
Idempotency-Key: checkout-order-1234
{ "from": { "address": "sender@example.com" },
"to": [{ "address": "user@example.com" }],
"subject": "Your receipt", "text": "Thanks" }If the response is lost, retry with the same key. The API can return the original acceptance instead of creating a second send.
A different payload with an existing key is a conflict. Generate a new key for a new message or batch.
Know what happened
A successful request means Clover accepted the message for asynchronous processing. It is not a claim that the recipient has received it yet.
The API validates the request and returns 202 with a message ID and request ID.
Workers persist dispatch state and retain retry context for transient failures.
Clover submits the delivery to the configured provider and records the provider response.
Provider events update delivered, bounced, and complained state and can arrive through webhooks.
Recover deliberately
Error responses use a stable envelope with an error type, message, optional field details, and a request ID. Redact credentials and message content from logs.
| Status | Meaning | Next action |
|---|---|---|
| 400 | The request shape or required field is invalid. | Fix the payload and do not retry unchanged. |
| 401 | The key is missing, invalid, expired, or not accepted. | Check the server-side secret and environment. |
| 403 | The key is valid but not allowed for this workspace or resource. | Check workspace, environment, and key scope. |
| 409 | The idempotency key conflicts with a different operation. | Inspect the original operation before creating a new key. |
| 503 | A dependency or provider path is temporarily unavailable. | Back off and retry with the same idempotency key. |
Keep the requestId with the failing operation. It is the safest handle for support and investigation.
Use your stack
The Go SDK and CLI are the supported runnable clients for the account/environment platform route. Keep the base URL and bearer key in server-side configuration, and pass an explicit idempotency key for each mutation.
import { CloverClient } from "@sendclover/sdk";
const clover = new CloverClient({
baseUrl: process.env.CLOVER_API_URL!,
apiKey: process.env.CLOVER_API_KEY!,
});
const accepted = await clover.platformMessages.send(
{
accountId: process.env.CLOVER_ACCOUNT_ID!,
environmentId: process.env.CLOVER_ENVIRONMENT_ID!,
},
{
from: { address: "sender@example.com" },
to: [{ address: "user@example.com" }],
subject: "Hello",
text: "Queued by Clover",
},
{ idempotencyKey: "send-2026-0001" },
);
console.log(accepted.id, accepted.requestId);Language availability
The TypeScript npm package, Go SDK, and CLI are supported runnable platform integrations. Python, Java, Rust, Swift, and Dart remain deferred until scoped routes and release evidence are complete.
Continue in Clover
Sign in to create a scoped API key, configure a sender, and inspect the first request from the control room.
Open Clover