Send email to your audience from any GitHub workflow. Release notes, incident updates, deploy notes, digests — one step, no server.
- uses: tiny-send/send@v1
with:
api-key: ${{ secrets.TINYSEND_API_KEY }}
list: ${{ vars.TINYSEND_LIST }}
subject: ${{ github.event.release.name }}
body: ${{ github.event.release.body }}GitHub notifications reach people who watch your repo. This reaches your audience — subscribers, users, customers — with real deliverability, archives, and unsubscribe handling. Get an API key and a list at tinysend.com; subscribers can sign up at your list's archive page or via a README badge.
api-key(required): tinysend API key, store as a repo secretlist(required): list id to send tosubject(required): email subjectbody: message content, markdown by defaultbody-file: read content from a file instead ofbodyformat:markdown(default),html, ortextchannel:email(default);smsandwhatsappcoming soondraft:trueto create the post without sending
post-id: id of the created poststatus:sentordraftrecipients: how many people it went to
on:
release:
types: [published]
jobs:
notify:
runs-on: ubuntu-latest
steps:
- uses: tiny-send/send@v1
with:
api-key: ${{ secrets.TINYSEND_API_KEY }}
list: ${{ vars.TINYSEND_LIST }}
subject: '${{ github.event.repository.name }} ${{ github.event.release.tag_name }} is out'
body: ${{ github.event.release.body }}Write a post by opening an issue. Label it announcement and it's emailed to your list — the issue tracker becomes your editor.
on:
issues:
types: [labeled]
jobs:
announce:
if: github.event.label.name == 'announcement'
runs-on: ubuntu-latest
steps:
- uses: tiny-send/send@v1
with:
api-key: ${{ secrets.TINYSEND_API_KEY }}
list: ${{ vars.TINYSEND_LIST }}
subject: ${{ github.event.issue.title }}
body: ${{ github.event.issue.body }}Open an issue labeled incident → subscribers get "we're investigating". Close it → they get the resolution.
on:
issues:
types: [labeled, closed]
jobs:
incident:
if: contains(github.event.issue.labels.*.name, 'incident')
runs-on: ubuntu-latest
steps:
- uses: tiny-send/send@v1
with:
api-key: ${{ secrets.TINYSEND_API_KEY }}
list: ${{ vars.TINYSEND_STATUS_LIST }}
subject: "${{ github.event.action == 'closed' && 'Resolved' || 'Investigating' }}: ${{ github.event.issue.title }}"
body: ${{ github.event.issue.body }}on:
deployment_status:
jobs:
notify:
if: github.event.deployment_status.state == 'success' && github.event.deployment.environment == 'production'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: tiny-send/send@v1
with:
api-key: ${{ secrets.TINYSEND_API_KEY }}
list: ${{ vars.TINYSEND_LIST }}
subject: 'New version live'
body-file: CHANGELOG.mdon:
push:
branches: [main]
paths: ['CHANGELOG.md']
jobs:
send:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: tiny-send/send@v1
with:
api-key: ${{ secrets.TINYSEND_API_KEY }}
list: ${{ vars.TINYSEND_LIST }}
subject: 'Changelog update'
body-file: CHANGELOG.mdGitHub is the scheduler, tinysend is the channel. Generate content with any step (script, API call, agent), then send it.
on:
schedule:
- cron: '0 9 * * MON'
jobs:
digest:
runs-on: ubuntu-latest
steps:
- id: write
run: |
echo "content<<EOF" >> "$GITHUB_OUTPUT"
gh api repos/${{ github.repository }}/releases --jq '.[0].body' >> "$GITHUB_OUTPUT"
echo "EOF" >> "$GITHUB_OUTPUT"
env:
GH_TOKEN: ${{ github.token }}
- uses: tiny-send/send@v1
with:
api-key: ${{ secrets.TINYSEND_API_KEY }}
list: ${{ vars.TINYSEND_LIST }}
subject: 'Weekly digest'
body: ${{ steps.write.outputs.content }}Any external system can trigger an email to your list via repository_dispatch — no server required.
on:
repository_dispatch:
types: [notify]
jobs:
send:
runs-on: ubuntu-latest
steps:
- uses: tiny-send/send@v1
with:
api-key: ${{ secrets.TINYSEND_API_KEY }}
list: ${{ vars.TINYSEND_LIST }}
subject: ${{ github.event.client_payload.subject }}
body: ${{ github.event.client_payload.body }}Agents running inside Actions (Claude Code action and friends) can report to humans through the same step — and via tinysend's MCP server and agent APIs, agents can manage the whole list themselves.
- audiences, not notifications: curated subscriber lists with archives, double opt-in, unsubscribe handled
- agent-first: agents can self-register (auth.md), use the MCP server, or this action
- multi-channel roadmap: same action will text and WhatsApp your audience —
channel: smsis coming, no workflow rewrite - SDK (
npm install tinysend) when you outgrow the action
MIT
a system operator product