Start with a Test credential and a server-side request. A successful response gives you a saved message ID, not proof of delivery. You can try a local API fixture without an account, or connect to a Stampwing installation you can already access.
Before you start #
- For
- Developers connecting a website, backend, or app for the first time.
- Bring
- Node.js 22+ for the downloadable sender; an accessible Stampwing installation for the authenticated path.
- Scope
- The public website is currently a resource and waitlist site. Hosted accounts and live sending are not generally available. The SDKs are local source packages; do not assume a registry release.
1. Choose the setup you actually have #
| Your situation | Start here | What success proves |
|---|---|---|
| No account or source checkout | Use the free local API fixture linked below. It needs Node.js, but no key, database, or DNS. | Your code handles a simulated HTTP contract. The fixture does not authenticate, persist across restarts, or send mail. |
| Access to a Stampwing installation | Continue with the project and Test-key steps on this page. | Your application reached Stampwing and queued a persisted Test message. |
| A source checkout and a local development machine | Follow Install Stampwing locally, then return here. | Your own database, web app, and demo worker work together. |
| Ready for real email | Complete Test first, then follow Go live. | Live readiness and provider evidence require separate checks. |
2. Create a project and choose Test #
- Open the workspace on the installation you can access. If /app returns you to the waitlist, you are on the public website; use the fixture or a local checkout instead.
- Create a project named after the application you are connecting. A project groups its domains, keys, templates, messages, and suppressions.
- Select Test. Open Connect your app or API keys and create a Test credential. For this tutorial, include email:send and email:read so you can both submit and inspect the result.
- Copy the secret when it appears and store it in your application’s private environment file. It is shown only once. If you lose it, create a replacement and revoke the lost key.
Prepare the tutorial files #
Create a folder just for this exercise. Keep all three files below in it; run the Node commands from that folder. Use a plain-text editor and enable hidden-file visibility if files starting with a dot are hidden. Check that your editor did not append .txt to either filename.
stampwing-tutorial/
.env.stampwing
.gitignore
stampwing-test-send.mjsKeep the environment file out of Git #
Add this line to the tutorial folder’s .gitignore before entering a key. In an existing project, append it to the existing ignore rules. This does not remove secrets that were already committed; if a key was exposed, replace it and revoke the old key.
.env.stampwing3. Save server-only configuration #
In a new tutorial folder, create .env.stampwing with the values below. Replace the key placeholder with your Test secret and POSTRUNE_EXPECTED_PROJECT_ID with the UUID from the intended project’s Settings → Project identifiers → Project ID. The project UUID is not the API key. For a remote installation, replace the origin with the exact HTTPS origin supplied by its operator. Do not append /api/v1 or an endpoint path.
Add .env.stampwing to .gitignore before saving a key. Do not use a NEXT_PUBLIC_ prefix, put a secret in browser code, paste it into an AI conversation, or commit it. The variable names retain Postrune for compatibility; the product is Stampwing.
POSTRUNE_BASE_URL=http://127.0.0.1:3017
POSTRUNE_API_KEY=REPLACE_WITH_YOUR_TEST_KEY
POSTRUNE_EXPECTED_PROJECT_ID=REPLACE_WITH_PROJECT_UUID_FROM_SETTINGS
POSTRUNE_OPERATION_KEY=stampwing-tutorial:first-message:0014. Run the guarded sender #
Download stampwing-test-send.mjs into the same folder as .env.stampwing. The script calls /api/v1/doctor first and refuses to submit with a Live key, missing permissions, or a different project. Sending requires POSTRUNE_EXPECTED_PROJECT_ID. The --check command validates the saved operation-key format and verifies Test permissions without submitting a message. It compares the credential’s project UUID with POSTRUNE_EXPECTED_PROJECT_ID and stops on a mismatch. Obtain that expected UUID independently from Settings → Project identifiers → Project ID; do not copy the doctor result into the field just to make the check pass. Run the final command only after those checks match; it sends one fixed synthetic message and reads its status. It has no npm dependencies.
node --version
node --env-file=.env.stampwing stampwing-test-send.mjs --check
node --env-file=.env.stampwing stampwing-test-send.mjs5. Check the response and the dashboard #
A successful send returns HTTP 202 with id, status, and mode. The example below is synthetic: your UUID will be different. The local demo can process the message before responding, so status may already be submitted or accepted. The status read can also remain queued while a worker catches up; neither is proof of real delivery.
- In Messages, select the same project and Test environment, then find the returned UUID.
- Open the message and inspect the stored timeline. Demo/Test events are simulated, including any accepted status. Nothing arrives in a real mailbox.
- Run the unchanged script again. It should return the same message UUID. If you change the content under the same operation key, expect an idempotency conflict.
- Save the message UUID and operation key with your test notes. You now have evidence of an authenticated API connection.
{
"id": "704ba836-ce9e-4f28-b7c6-f54cf89c7385",
"status": "queued",
"mode": "demo"
}If the last step fails, recover the existing message #
The script prints an accepted UUID before looking up progress. If that lookup fails, the send remains accepted; exit code 2 means only the status check failed. Read the same UUID with --status instead of creating a new operation. This read needs email:read and no operation key. Replace the sample UUID below with your actual result.
| Result | What to do |
|---|---|
| Exit 0 | The requested Test check, send/status sequence, or status lookup completed. |
| Exit 1 before submission | Fix configuration or permissions. This run did not submit a message. |
| Exit 1 during submission | Acceptance was not confirmed. Inspect Messages and preserve the original key and content. |
| Exit 2 | The message was accepted, but status could not be read. Use --status with the printed UUID. |
node --env-file=.env.stampwing stampwing-test-send.mjs --status 704ba836-ce9e-4f28-b7c6-f54cf89c73856. Connect a real business action #
Move sending into your backend. Resolve the recipient and content from an authorized action such as a completed signup or paid invoice. Save the event identity, frozen content, and returned message ID. A public form must not be able to choose arbitrary recipients or senders using your key.
Install the SDK and connect Node.js or Next.js →
Sources and further reading
Written for Stampwing with AI assistance and checked against the linked documentation. Examples are educational; simulated results are labelled. How these resources are maintained.