Clojure library for the Resend API.
Add the following dependency to your deps.edn:
net.clojars.laisfrigerio/resend-clojure {:mvn/version "0.1.0"}
Or add the following dependency to your project.clj:
[net.clojars.laisfrigerio/resend-clojure "0.1.0"]
First, you need to get an API key, which is available in the Resend Dashboard.
(require '[resend.core :as resend])
(def client (resend/create-client "re_xxxx...xxxxxx"))
You can also configure the client via an environment variable:
;; Reads RESEND_API_KEY from the environment automatically
(def client (resend/create-client))
(require '[resend.core :as resend]
'[resend.api.emails :as emails])
(def client (resend/create-client))
(let [{:keys [data error]} (emails/send! client
{:from "you@example.com"
:to ["user@gmail.com"]
:subject "Hello, world!"
:text "It works!"})]
(if error
(println "Error:" (:message error))
(println "Email sent:" (:id data))))
Note: In order to send from your own domain, you will first need to verify your domain in the Resend Dashboard.
(let [{:keys [data error]} (emails/send! client
{:from "you@example.com"
:to ["user@gmail.com"]
:subject "Hello, world!"
:html "<strong>It works!</strong>"})]
(if error
(println "Error:" (:message error))
(println "Email sent with HTML:" (:id data))))
(emails/send! client
{:from "you@example.com"
:to ["user@gmail.com"]
:cc ["cc@example.com"]
:bcc ["bcc@example.com"]
:reply-to "reply@example.com"
:subject "Hello, world!"
:html "<strong>It works!</strong>"})
(emails/send! client
{:from "you@example.com"
:to ["user@gmail.com"]
:subject "Invoice attached"
:html "<p>Please find your invoice attached.</p>"
:attachments [{:filename "invoice.pdf"
:content (java.util.Base64/getEncoder
(.encodeToString (slurp "invoice.pdf")))}]})
(emails/send! client
{:from "you@example.com"
:to ["user@gmail.com"]
:subject "Hello, world!"
:html "<strong>It works!</strong>"
:tags [{:name "category" :value "welcome"}
{:name "user-id" :value "12345"}]})
(emails/send-batch! client
[{:from "you@example.com"
:to ["user1@gmail.com"]
:subject "Welcome, Alice!"
:html "<p>Hello Alice!</p>"}
{:from "you@example.com"
:to ["user2@gmail.com"]
:subject "Welcome, Bob!"
:html "<p>Hello Bob!</p>"}])
(require '[resend.api.emails :as emails])
(let [{:keys [data error]} (emails/get client "email-id-here")]
(when data
(println "From:" (:from data))
(println "To:" (:to data))
(println "Subject:" (:subject data))))
(emails/update! client "email-id-here"
{:scheduled-at "2024-12-31T10:00:00.000Z"})
(emails/cancel! client "email-id-here")
All functions return a map with :data and :error keys. By default, no exceptions are thrown:
(let [{:keys [data error]} (emails/send! client params)]
(if error
;; error is a map: {:message "..." :name "..." :status-code 422}
(handle-error error)
;; data is a map with the API response
(handle-success data)))
| Function | Description |
|---|---|
emails/send! | Send an email |
emails/send-batch! | Send a batch of up to 100 emails |
emails/get | Retrieve a sent email by ID |
emails/update! | Update a scheduled email |
emails/cancel! | Cancel a scheduled email |
(require '[resend.api.contacts :as contacts])
;; Create a contact
(contacts/create! client "audience-id" {:email "user@example.com" :first-name "Alice"})
;; List contacts in an audience
(contacts/list client "audience-id")
;; Get a contact
(contacts/get client "audience-id" "contact-id")
;; Update a contact
(contacts/update! client "audience-id" "contact-id" {:first-name "Alicia"})
;; Remove a contact
(contacts/delete! client "audience-id" "contact-id")
(require '[resend.api.audiences :as audiences])
;; Create an audience
(audiences/create! client {:name "Newsletter Subscribers"})
;; List all audiences
(audiences/list client)
;; Get an audience
(audiences/get client "audience-id")
;; Delete an audience
(audiences/delete! client "audience-id")
(require '[resend.api.broadcasts :as broadcasts])
;; Create a broadcast
(broadcasts/create! client
{:audience-id "audience-id"
:from "you@example.com"
:subject "Monthly Newsletter"
:html "<p>What's new this month...</p>"})
;; Send a broadcast
(broadcasts/send! client "broadcast-id")
;; List all broadcasts
(broadcasts/list client)
;; Get a broadcast
(broadcasts/get client "broadcast-id")
;; Delete a broadcast
(broadcasts/delete! client "broadcast-id")
(require '[resend.api.domains :as domains])
;; Create a domain
(domains/create! client {:name "example.com"})
;; List all domains
(domains/list client)
;; Get a domain
(domains/get client "domain-id")
;; Verify a domain
(domains/verify! client "domain-id")
;; Update a domain
(domains/update! client "domain-id" {:click-tracking true :open-tracking true})
;; Delete a domain
(domains/delete! client "domain-id")
(require '[resend.api.api-keys :as api-keys])
;; Create an API key
(api-keys/create! client {:name "Production Key" :permission "full_access"})
;; List all API keys
(api-keys/list client)
;; Delete an API key
(api-keys/delete! client "api-key-id")
(require '[resend.api.webhooks :as webhooks])
;; Create a webhook
(webhooks/create! client
{:endpoint "https://yourapp.com/webhooks/resend"
:events ["email.sent" "email.delivered" "email.bounced"]})
;; List all webhooks
(webhooks/list client)
;; Get a webhook
(webhooks/get client "webhook-id")
;; Delete a webhook
(webhooks/delete! client "webhook-id")
resend-clojure uses hato as the default HTTP client. You can plug in your own adapter by implementing the HttpAdapter protocol:
(require '[resend.internal.http :refer [HttpAdapter]])
(defrecord MyHttpAdapter []
HttpAdapter
(request [_ opts]
;; implement using your preferred HTTP client
))
(def client (resend/create-client "re_xxxx...xxxxxx"
{:http-adapter (->MyHttpAdapter)}))
(def client (resend/create-client "re_xxxx...xxxxxx"
{:timeout-ms 5000
:max-retries 3
:retry-on #{429 500 502 503 504}
:base-backoff-ms 200}))
Please see CONTRIBUTING.md for details on how to contribute to this project.
Leiningen requires Java 8+. Install via SDKMAN to manage java versions (recommended):
curl -s "https://get.sdkman.io" | bash
sdk install java
Or via Homebrew (macOS):
brew install openjdk
brew install leiningen
Or manually:
curl -o ~/bin/lein https://raw.githubusercontent.com/technomancy/leiningen/stable/bin/lein
chmod +x ~/bin/lein
lein # downloads itself on first run
Verify installation:
lein -v
git clone https://github.com/laisfrigerio/resend-clojure.git
cd resend-clojure
lein deps
After cloning, run once to activate the pre-commit hook:
bash scripts/setup-hooks.sh
This configures Git to run automatically on every git commit:
lein lint-fix — formats the codelein test — runs the test suite; if any test fails, the commit is abortedlein test
lein lint # check only
lein lint-fix # check and auto-fix
MIT License — see LICENSE for details.
Can you improve this documentation?Edit on GitHub
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |