Skip to main content
These examples build on the client setup in each language guide. Every client uses https://api.signal.apollodeploy.com by default.
Run SDK code only in a trusted server, worker, or command-line process. Keep SIGNAL_API_KEY in your server-side secret manager.

Send HTML with retry protection

Include a plain-text fallback for clients that cannot render HTML. Use a stable idempotency key for one logical message so a worker can safely retry an interrupted request. Keep the same key and payload on every retry. The snippets below assume you already created the authenticated client shown in the corresponding language guide.
TypeScript
Do not generate a new idempotency key when retrying the same logical message. A new key represents a new send and can create a duplicate email.

Test without delivering

Add the language-specific test-mode field to the same request. Signal validates and records the message without handing it to the delivery provider. Use a distinct idempotency key for the test. Reusing a production key would refer to the existing logical send. See Test mode for expected status and validation behavior.

Use a framework integration

The framework guides show where to create and reuse the client, where to store the API key, and how to keep sending off the public client path.

Next.js Route Handler

Send from a server-only route without exposing the key to a Client Component.

Express route

Reuse one client and pass failures to your normal error middleware.

Rails integration

Configure the Rails gem once and send from a service or background job.

Laravel integration

Inject the shared PHP client through the package service provider.

Follow the accepted message

The send response contains the Signal email id and initial status. Acceptance is not final delivery. Store the ID with your application record, then use signed webhooks or the email timeline to follow delivery, bounce, complaint, and engagement events.

Idempotency keys

Design stable keys for jobs, batches, and retries.

Email timelines

Understand message states after API acceptance.