Encrypting sensitive API request payloads with JWE (RSA-OAEP-256 + A256GCM) in AutoSend

We want to send sensitive user information (like PII in custom contact properties) via the AutoSend API, but our compliance policy requires application-layer end-to-end encryption before transmission. Does AutoSend support encrypted JSON request bodies, and how do we set up JWE encryption with JWKS key rotation?

Yes! AutoSend natively supports opt-in JWE (JSON Web Encryption) compact payloads on all public /v1 endpoints (e.g. /v1/mails/send, /v1/contacts/email).

How JWE Payload Encryption Works:

  1. Encryption Standard: Uses RSA-OAEP-256 for key management and A256GCM for content encryption with RSA 2048-bit keys.
  2. Fetch JWKS: Fetch AutoSend’s active public key from https://api.autosend.com/v1/jwks.json.
  3. HTTP Headers: Include X-Payload-Encryption: jwe and X-Key-Id: <kid> in your API request, with {"encryptedData": "<JWE_STRING>"} in the body.

Node.js Implementation Example (using jose):

import { importJWK, CompactEncrypt } from 'jose';

const API_BASE = 'https://api.autosend.com';
const JWE_ALG = 'RSA-OAEP-256';
const JWE_ENC = 'A256GCM';

async function sendEncryptedMail(payload: any, apiKey: string) {
  // 1. Fetch JWKS public key
  const jwksRes = await fetch(`${API_BASE}/v1/jwks.json`);
  const { keys } = await jwksRes.json();
  const jwk = keys[0]; // Active key is listed first
  const publicKey = await importJWK(jwk, JWE_ALG);

  // 2. Encrypt payload to JWE string
  const data = new TextEncoder().encode(JSON.stringify(payload));
  const encryptedData = await new CompactEncrypt(data)
    .setProtectedHeader({ alg: JWE_ALG, enc: JWE_ENC, kid: jwk.kid })
    .encrypt(publicKey);

  // 3. Dispatch to AutoSend API
  const res = await fetch(`${API_BASE}/v1/mails/send`, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${apiKey}`,
      'Content-Type': 'application/json',
      'X-Payload-Encryption': 'jwe',
      'X-Key-Id': jwk.kid,
    },
    body: JSON.stringify({ encryptedData }),
  });

  return await res.json();
}

Relevant Documentation