Get started
Quickstart
By the end of this page you'll have an API key, a connected inbox, and a real email out the door — all driven by HTTP. Total time: about five minutes.
1. Create a workspace and API key
Sign in with a magic link. The first time you log in, Clement creates a workspace for you. Open Settings → API keys and click Create key.
Pick the write scope to start — that's enough to create
contacts and sends, but not to revoke other keys or rotate webhooks.
The secret is shown once; copy it somewhere safe. If you lose it,
rotate.
export CLEMENT_API_KEY=cl_live_a1b2c3d4e5f6... 2. Connect an inbox
Sends always go through a connected inbox. For Gmail and Outlook, OAuth consent has to happen in a real browser session — call:
curl -X POST "https://api.clement.so/v1/inboxes/google/connect_link" \
-H "Authorization: Bearer $CLEMENT_API_KEY" The response carries a one-time URL. Open it in a browser, sign in to the Google account you want to send from, and grant the requested scopes. Once you land on the success page, the inbox is ready — list inboxes to grab its ID:
curl "https://api.clement.so/v1/inboxes" \
-H "Authorization: Bearer $CLEMENT_API_KEY" For SMTP/IMAP accounts, no browser handoff is required — see the inboxes reference for the credential-based path.
3. Send your first email
POST /v1/sends is the primitive. Replace the inbox ID with
yours, then run the call. The Idempotency-Key header is
required — generate any UUID; same UUID + same body within 24 hours is
safe to retry.
curl
curl -X POST "https://api.clement.so/v1/sends" \
-H "Authorization: Bearer $CLEMENT_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
--data '{
"inbox_id": "inb_01HZ8X3J9K7P2QV6R5N4M3T2L1",
"to": [{"email": "alice@example.com", "name": "Alice"}],
"subject": "Quick question about your stack",
"body_text": "Hi {{first_name}}, would love to chat — does Tuesday work?",
"variables": {"first_name": "Alice"}
}' TypeScript
import { Clement } from "@clement/sdk";
const c = new Clement({ apiKey: process.env.CLEMENT_API_KEY! });
const send = await c.sends.create(
{
inbox_id: "inb_01HZ8X3J9K7P2QV6R5N4M3T2L1",
to: [{ email: "alice@example.com", name: "Alice" }],
subject: "Quick question about your stack",
body_text: "Hi {{first_name}}, would love to chat — does Tuesday work?",
variables: { first_name: "Alice" },
},
{ idempotencyKey: crypto.randomUUID() },
);
console.log(send.id, send.state);
The response is the full Send resource with state
scheduled. The worker picks it up, sends via Gmail, and
transitions through sending → sent. The whole thing takes a
second or two.
4. Watch the event fire
Every state transition emits an event. To watch them without setting up a
webhook endpoint, poll /v1/events filtered to the send:
curl "https://api.clement.so/v1/events?resource_id=$SEND_ID" \
-H "Authorization: Bearer $CLEMENT_API_KEY"
You'll see send.scheduled, send.sending,
send.sent. Once the recipient opens or replies you'll also
see message.opened, message.clicked,
message.replied.
For real integrations, point a webhook endpoint at
POST /v1/webhooks instead of polling — see the
webhooks guide.
Next steps
- Send your first email — single, fan-out, scheduled, threaded.
- Import contacts — CSV upload + polling.
- Run a campaign — audience × sequence × inbox.
- Webhooks — signed delivery, retry policy, deliveries log.
- API reference — every endpoint.