API reference

REST examples against https://api.piisend.com/api/v1 in curl, JavaScript, and Python.

Call the Piisend REST API directly—each example has tabs for cURL, JavaScript (fetch), and Python (httpx). There is no installable SDK package. Delivery routing is handled on the server; your app only needs HTTPS and an API key.

Prerequisites

Create an API key with the emails:send scope (and templates:write if you create templates via API). Keys are created from the dashboard under API → Keys.

Authentication

Base URL: https://api.piisend.com/api/v1. Send JSON with Authorization: Bearer <YOUR_API_KEY> (pii_… prefix). For self-hosted deployments, point requests at your API host instead.

Authorization: Bearer <YOUR_API_KEY>
Content-Type: application/json

Send email — raw HTML or text

Omit template_id; provide subject plus at least one of html or text. Works for transactional and marketing messages.

curl -sS -X POST "https://api.piisend.com/api/v1/emails" \
  -H "Authorization: Bearer $PIISEND_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "to": ["alice@example.com"],
    "subject": "Welcome to Example",
    "html": "<h1>Hi Alice</h1><p>Thanks for signing up.</p>",
    "text": "Hi Alice, thanks for signing up."
  }'

Send email — template

Use a dashboard template and pass template_vars. Do not send subject, html, or text in the same request as template_id.

curl -sS -X POST "https://api.piisend.com/api/v1/emails" \
  -H "Authorization: Bearer $PIISEND_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "to": ["alice@example.com"],
    "template_id": "YOUR_TEMPLATE_ID",
    "template_vars": {
      "firstName": "Alice",
      "signupUrl": "https://app.example.com/welcome"
    }
  }'

OTP email (with idempotency)

Pass Idempotency-Key so retries after network errors do not double-send the same OTP.

curl -sS -X POST "https://api.piisend.com/api/v1/emails" \
  -H "Authorization: Bearer $PIISEND_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: otp:user@example.com:842913" \
  -d '{
    "to": ["user@example.com"],
    "template_id": "YOUR_OTP_TEMPLATE_ID",
    "template_vars": {
      "name": "Rao",
      "otp_code": "842913",
      "expires_in": "10 minutes"
    }
  }'

Create template

POST /templates creates a reusable template; use its id when sending.

curl -sS -X POST "https://api.piisend.com/api/v1/templates" \
  -H "Authorization: Bearer $PIISEND_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "otp-login",
    "subject": "Your OTP code is {{otp_code}}",
    "html_body": "<h1>Hi {{name}}</h1><p>Your OTP is <b>{{otp_code}}</b></p>",
    "text_body": "Hi {{name}}, your OTP is {{otp_code}}."
  }'

Errors

Non-2xx responses return JSON with a detail field when available.

# HTTP 4xx/5xx — body is JSON, e.g. {"detail":"..."}
curl -i -X POST "https://api.piisend.com/api/v1/emails" ...

Domain behavior

If you omit from_ (or have no verified domain yet), Piisend sends from the shared platform domain (see your dashboard for the exact address). After DNS verification, set from_ to your verified sender and optionally domain_id when sending.

Useful endpoints

  • POST /emails — send transactional, marketing, or templated mail
  • GET /emails — list sent or scheduled mail
  • POST /templates — create reusable templates
  • GET /templates — list templates for your workspace

Documentation

Integrate with the REST API

Quickstart, API reference, and webhooks—everything you need to send from your app.