GitHub Actions

Send email and SMS from your CI workflows with two actions on the GitHub Marketplace:

Action Use for
pingram-io/github-actions-send-email Deploy notifications, build failure alerts, release summaries
pingram-io/github-actions-send-sms Paging on-call, urgent alerts

Both are bundled with no runtime dependencies, so nothing is installed on the runner.


Setup

  1. Grab a pingram_sk_... key from the API Keys page in your Pingram dashboard.
  2. In your repository, go to Settings → Secrets and variables → Actions and add a repository secret named PINGRAM_API_KEY.

That’s it. There is no notification type to create first — type is any string you choose, and it is what the send is grouped under in Logs and Insights.


Send an email

- uses: pingram-io/github-actions-send-email@v1
with:
api-key: ${{ secrets.PINGRAM_API_KEY }}
type: deploy-status
to: team@example.com
subject: Deploy succeeded
html: <p><code>${{ github.sha }}</code> is live.</p>

Notify on a failed build

if: failure() is what turns this into a build failure notification — GitHub only runs the step when something earlier in the job failed. Use if: always() if you want a result either way.

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci && npm test
- uses: pingram-io/github-actions-send-email@v1
if: failure()
with:
api-key: ${{ secrets.PINGRAM_API_KEY }}
type: ci-alerts
to: oncall@example.com
subject: '${{ github.workflow }} failed on ${{ github.ref_name }}'
html: |
<p><a href="${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}">
View the failed run</a></p>

Email inputs

Name Required Default Description
api-key yes Pingram API key (pingram_sk_...)
type yes Label used to group the send in your logs
to yes Recipient email, or a comma-separated list
subject yes Subject line
html yes HTML body
from-name no Sender display name
from-address no Sender address on a verified domain
preview-text no Inbox preview text
reply-to no Comma-separated reply-to addresses
cc no Comma-separated CC addresses
bcc no Comma-separated BCC addresses
schedule no ISO 8601 timestamp to send at instead of now
region no us us, eu or ca
fail-on-error no true Fail the step when the send fails

Send an SMS

Phone numbers use E.164 format. Quote them in YAML — unquoted, +1555... is ambiguous and some parsers will mangle it. Pass a comma-separated list to notify several people; each number gets its own SMS.

- uses: pingram-io/github-actions-send-sms@v1
if: failure()
with:
api-key: ${{ secrets.PINGRAM_API_KEY }}
type: oncall-page
to: '+15551234567, +15559876543'
message: 'Production deploy failed: ${{ github.repository }}'

Pingram handles A2P 10DLC registration, carrier routing, and opt-out handling for US SMS — see SMS senders and A2P 10DLC.

SMS inputs

Name Required Default Description
api-key yes Pingram API key (pingram_sk_...)
type yes Label used to group the send in your logs
to yes E.164 phone number, or a comma-separated list
message see note Message body
from no Sender number override (E.164)
media-urls no Comma-separated media URLs for MMS
schedule no ISO 8601 timestamp to send at instead of now
region no us us, eu or ca
fail-on-error no true Fail the step when the send fails

message is required unless you set media-urls, which sends a media-only MMS.


Using the tracking id

Both actions set a tracking-id output you can use in later steps. Give the step an id to reference it. When to has multiple recipients, the output is a comma-separated list of ids — one per successful send.

- uses: pingram-io/github-actions-send-email@v1
id: notify
with:
api-key: ${{ secrets.PINGRAM_API_KEY }}
type: deploy-status
to: team@example.com, oncall@example.com
subject: Deployed
html: <p>Done.</p>
- run: |
echo "Sent as ${{ steps.notify.outputs.tracking-id }}"

The same ids appear under Logs in your dashboard, so they are what you use to trace a specific send.


Keeping notifications from blocking a deploy

By default the step fails the job when a send fails, which makes a silent notification outage visible. When a notification should never be able to break a pipeline, set fail-on-error: false to log a warning instead.

- uses: pingram-io/github-actions-send-email@v1
with:
api-key: ${{ secrets.PINGRAM_API_KEY }}
type: deploy-status
to: team@example.com
subject: Deployed
html: <p>Done.</p>
fail-on-error: false

Regions

Set region to match the region your Pingram account lives in. us is the default.

Region API
us api.pingram.io
eu api.eu.pingram.io
ca api.ca.pingram.io

A key from one region will return a 403 against another, so this is worth checking first if a send is rejected.


Security

Always pass the key in from a secret rather than hardcoding it. The action registers the key with the runner as its first step, so it is masked as *** anywhere it would otherwise appear in a log — including in the step’s own input echo.

For different keys per environment, use environment secrets and add an environment: key to the job.


Versions

@v1 tracks the latest v1.x release, which is what most workflows want. To pin exactly, use a commit SHA:

- uses: pingram-io/github-actions-send-email@<commit-sha>