SMTP + REST APIStandalone, or alongside tinyEmail

Transactional email that reports back.

A developer-friendly SMTP relay and transactional email service, powered by our email delivery infrastructure. Send password resets, sign-in codes, receipts and alerts over SMTP or a REST API, and hear back about every one.

Live relay · illustrative
Your app
POST /email/campaign
tinyRelay
DKIM-signed
Inbox
ann@example.com
Subject
Reset your password
metadata · user_id: u_1042
    Simulate a bounce
    Send again
    7
    signed webhook event types
    19
    documented bounce categories
    10
    metadata keys echoed per send
    24 h
    duplicate suppression
    5 days
    event replay window

    All figures come from the tinyRelay docs, not marketing estimates.

    How it works

    Six steps from your app to a signed answer.

    01Connect

    SMTP or a REST API. Your choice.

    Point existing software at the SMTP relay with the credentials we issue, or send with one HTTP request. Same infrastructure, same sending domains.

    SMTP credentialsPOST /email/campaignAny HTTP client
    02Personalise

    One request. Everyone gets their own.

    Send to many recipients in a single request, each with their own merge attributes and their own metadata.

    [FIRST_NAME] merge tagsPer-recipient metadataUp to 10 keys
    03Authenticate

    Sign your mail with one record.

    Add one CNAME for DKIM. An API endpoint checks your DKIM and SPF records before you send.

    DKIM CNAMEPUT /domain/dns/check
    04Deliver

    From your app to the inbox.

    tinyRelay sends on our email delivery infrastructure, run by the same company and team behind tinyEmail.

    DKIM-signedTracking optionalLink wrapping
    05Hear back

    Every event comes back, signed.

    SEND, DELIVERED, OPEN and CLICK, plus BOUNCED, UNSUBSCRIBE and SPAM. Signed, retried, de-duplicated for 24 hours, replayable for 5 days.

    7 event typesSvix signatures5-day replay
    06Handle bounces

    Know exactly why it bounced.

    Every BOUNCED event carries one of 19 documented categories, so your app knows whether to retry, investigate or stop sending.

    HARD_BOUNCEDSOFT_BOUNCED19 categories
    01 · CONNECT
    SMTP
    Point your app at us

    Credentials issued at onboarding. Any SMTP client.

    REST API
    One HTTP request

    POST /email/campaign with X-RELAY-ACCESS-TOKEN.

    Your app
    tinyRelay
    One request · request metadata { tenant_id: acme }
    AHi Ann, reset your passwordattributes { FIRST_NAME: "Ann" }order_id: SO-1
    BHi Bob, reset your passwordattributes { FIRST_NAME: "Bob" }order_id: SO-2
    CHi Chen, reset your passwordattributes { FIRST_NAME: "Chen" }order_id: SO-3

    Metadata merges per recipient; the recipient's keys win. Up to 10 keys.

    The one record you add
    tec1._domainkey.acme.com
    CNAME → tec1.dkim.tinyemail.com
    PUT /domain/dns/check · illustrative
    DKIMChecking…
    SPFChecking…
    Your app
    tinyRelay
    Inbox

    Example email · illustrative

    • SENDSent to the receiving serversigned ✓
    • DELIVEREDReceiving server accepted itsigned ✓
    • OPENOpened by the recipientsigned ✓
    • CLICKurl: acme.com/reset?t=…signed ✓

    svix-id · svix-timestamp · svix-signature on every request · metadata { user_id: u_1042 }

    BOUNCED · SOFT_BOUNCED · bounceCategory "22"
    Mailbox full

    The recipient's mailbox or quota is full.

    WHAT TO DO ·Retry later
    BOUNCED · HARD_BOUNCED · bounceCategory "10"
    Bad email address → suppress the address
    Use cases

    Built for the email your app has to send.

    Password resets that arrive, or tell you why not

    Send the reset link the moment it is requested. If the address is dead you get a BOUNCED event, so your app can say so instead of leaving the user waiting.

    • Attach the user ID as metadata; it is on every event
    • CLICK events carry the exact link clicked
    • Hard bounces tell you to stop sending to that address
    Password reset emails →
    metadata · user_id: u_1042watch for · BOUNCED · CLICK

    Example email · illustrative

    One-time codes and verification emails

    Sign-up confirmations and login codes need to land now. DKIM signing and a DNS check endpoint help them get there; DELIVERED tells you when they did.

    • Turn off tracking per request for code emails
    • DELIVERED confirms the receiving server accepted it
    • Per-recipient metadata in a single request
    Verification code emails →
    metadata · user_id: u_1042watch for · DELIVERED · BOUNCED

    Example email · illustrative

    Receipts, shipping and invoice emails

    Send order confirmations straight from your backend. The order ID you attach comes back on every delivery event, so support can see what happened to each one.

    • order_id echoed on SEND, DELIVERED, OPEN and CLICK
    • One request can send to many recipients
    • Works over SMTP from your store platform too
    Order confirmation emails →
    metadata · order_id: SO-1001watch for · DELIVERED · CLICK

    Example email · illustrative

    Security, billing and account notifications

    New sign-ins, failed payments and plan changes. Send them over SMTP or the API and keep a signed record of every delivery event.

    • Signed webhooks you can verify
    • SPAM and UNSUBSCRIBE events come back too
    • RFC 8058 one-click unsubscribe where it applies
    Account notification emails →
    metadata · tenant_id: acmewatch for · DELIVERED · SPAM

    Example email · illustrative

    Features

    Everything a transactional sender needs. Each one documented.

    Flip the switches. Every behaviour below is in the tinyRelay docs.

    SMTP or REST API. Same infrastructure.

    Call the REST API from your code. Give each recipient their own merge attributes and metadata in one request.

    Endpoint
    POST /email/campaign
    Auth header
    X-RELAY-ACCESS-TOKEN
    Response
    202 · requestId

    Connect existing software with the SMTP credentials issued at onboarding. Nothing to integrate.

    Credentials
    Issued at onboarding
    Works with
    Any SMTP client
    Host · port
    [to confirm]

    Your IDs on every event

    Attach metadata; it comes back on every webhook.

    2 / 10 keys

    10 keys is the documented maximum per send.

    DKIM in one record

    Add one CNAME, then check it with the API.

    tec1._domainkey.acme.com
    CNAME tec1.dkim.tinyemail.com
    DKIM Not checkedCheck DNS

    Tracking, your way

    One switch per request. Optional link wrapping.

    Open + click tracking
    Link wrapping

    Locked down by default

    Keys in a header, callers allowlisted, webhooks signed.

    • API key in X-RELAY-ACCESS-TOKEN
    • Your calling IPs allowlisted
    • HMAC-signed webhooks from a fixed IP
    • RFC 8058 one-click unsubscribe headers
    Security →
    Webhooks

    What happens to an event, over time.

    Tap through one event's life. Delivery semantics, written down.

    The moment it happens
    Signed and posted to your endpoint

    Every request carries svix-id, svix-timestamp and svix-signature headers. Delivery is at least once.

    Your endpoint times out or returns 5xx
    We retry, with the same delivery id

    Every retry of an event repeats the same svix-id, so deduplicate your processing on it.

    Within 24 hours
    Repeats are suppressed before they leave us

    A repeat of an event you were already sent is dropped. A genuine second open or click is a new event and still reaches you.

    After 24 hours
    Size your own dedupe store

    Our duplicate suppression lasts 24 hours. Beyond it, a re-processed event could reach you again.

    Up to 5 days
    Missed events can be replayed

    Event payloads are kept for 5 days, so a missed event can be redelivered. After that it is gone.

    Is this webhook really from us?

    Allowlisting an IP isn't authentication. Here's the check, step by step.

    1
    svix-id
    Stable across retries. Deduplicate on it.
    2
    svix-timestamp
    Reject requests outside your tolerance; five minutes is a reasonable default.
    3
    svix-signature
    HMAC-SHA256 over id.timestamp.body with your endpoint secret, compared in constant time.
    Not checked yetVerify sample request
    Full guide: verify webhook signatures →
    Bounces

    Every bounce tells your app what to do next.

    Each BOUNCED event carries one of 19 documented categories. They come down to four answers. Pick one to see the categories behind it.

    10Bad email addressDelivery should not be attempted again. Usually the mailbox does not exist.
    90UnsubscribeThe recipient asked to be removed. Not a delivery failure, but final.
    20GeneralA possibly temporary failure; the address may or may not be valid.
    21DNS failureA DNS lookup failed along the way.
    22Mailbox fullThe recipient's mailbox or quota is full.
    23Message too largeRejected because of the message size.
    24Missing MX recordThe destination domain has no MX record.
    29Unable to connectCould not connect to the remote server.
    40General bounceA bounce with no more specific category.
    70Transient bounceA temporary delay in transmission.
    50General blockRejected for a reason no specific block category covers.
    51Known spammerThe remote server considers the sending server a spammer, often via a block list.
    52Spam detectedThis message's content was classified as spam.
    53Attachment detectedRejected because of one or more attachments.
    54Relay deniedThe remote server refused to relay the message.
    55SPF/DKIM/DMARCRefused on authentication policy.
    59Unable to connectCould not connect to the remote server, like code 29.
    0Non-bounceA message that could not be classified as a bounce.
    60Auto-replyGenerated by an auto-responder, such as a vacation reply.

    Every BOUNCED event also carries bounceDescription and bounceStatus: the receiving server's own words and DSN code.

    Full bounce code reference →
    SMTP or API?

    Three questions. One clear answer.

    Both run on the same infrastructure. It depends on how your app sends today.

    Is the email sent by existing software (a framework mailer, CMS or server)?
    Do you need your own IDs per recipient, echoed on every webhook?
    Can you add a few lines of HTTP code?
    Built by the team behind tinyEmail

    One company. Every kind of email.

    Use tinyRelay on its own for the email your app triggers, or alongside tinyEmail, which runs your campaigns and newsletters with its own REST API. Same company, same delivery infrastructure.

    How tinyEmail and tinyRelay fit together →
    tinyRelay
    What your app triggers

    Resets, codes, receipts, shipping and billing notices, alerts.

    tinyEmail
    What your team sends

    Campaigns, newsletters, segments and automations.

    Pricing

    Priced on your volume. Tell us what you send.

    Pick what applies and we'll prepare a quote.

    Request pricing

    How onboarding works

    1. 1
      Tell us about your sending
      Messages, method and the domains you send from.
    2. 2
      We set up your domains
      Sender domains added; DKIM signed with one CNAME.
    3. 3
      Get your credentials
      SMTP credentials and an API key; your webhook endpoint registered.
    4. 4
      Send
      The first request returns 202 with a requestId; events start arriving.
    How onboarding works →
    FAQ

    Questions developers ask first.

    Short answers. The docs have the long ones.

    What is tinyRelay?

    A developer-friendly SMTP relay and transactional email service, powered by tinyCo's email delivery infrastructure. You send transactional and application-generated email using SMTP or a REST API, on its own or alongside tinyEmail.

    Both run on the same infrastructure. Use SMTP when existing software already sends email; use the REST API when you want one request to send to many recipients, each with their own merge attributes and metadata.

    There are no packages to install. Anything that can make an HTTP request works, and the docs include examples for Node.js, Python, PHP, Ruby, Go and cURL.

    Seven event types come back to your endpoint as signed webhooks: SEND, DELIVERED, BOUNCED, OPEN, CLICK, UNSUBSCRIBE and SPAM. Your metadata is on every one.

    Pricing is based on your monthly sending volume. Tell us what you send and we prepare a quote.

    Submit the Get started form. Our team sets up your sending domains with you and sends your SMTP credentials and API key.

    Get started

    Send transactional email with a service that reports back.

    SMTP relay or REST API, standalone or alongside tinyEmail. Tell us what you send and our team sets you up.