Skip to main content

@lettrove/node

npm install @lettrove/node

Node.js 20 or newer, and edge runtimes (it uses only fetch and Web Crypto). It refuses to run in a browser.

import { Lettrove, LettroveApiError, verifyWebhook } from '@lettrove/node';

const lettrove = new Lettrove({ secretKey: process.env.LETTROVE_SECRET_KEY! });

new Lettrove(options)​

OptionTypeDefault
secretKeystringrequiredlt_sk_test_… or lt_sk_live_…, from your environment. A publishable key, a cut-off key or a key with spaces is refused at once, with a message saying which.
timeoutMsnumber15000How long to wait for an answer.
fetchtypeof fetchthe globalYour own fetch, for runtimes or tests that need one.

lettrove.environment is 'test' or 'live', read from the key.

tokens.create(input) → { token, expiresAt }​

Input
user.idRequired. Your own id for the person (1–256 characters).
originRequired. The page the editor opens on: the request's Origin header.
ttlOptional. 60–900 seconds; default 900.

Minting tokens

designs.list(input) → { designs, nextCursor }​

Input
user.idRequired.
limit1–200, default 50.
cursornextCursor from the previous page.

Each design: { id, name, mode, revision, createdAt, updatedAt }, newest first.

designs.get(designId, { user }) → Design​

The summary fields, plus doc: the design document.

designs.export(designId, input)​

Input
user.idRequired.
merge{ contact?, unsubscribeUrl?, preferencesUrl? } — Merge tags
text{ links?, images?, preheader? } — how the plain text is written
format'html' (default), 'pdf', 'png' or 'zip'
fullPageFor 'png': the whole design (default) or the first screen

With format 'html' or none, resolves with ExportedDesign: exportId, designId, revision, mode, html, chunks, text, subject, preheader, mergeTags, rendererVersion, bytes, warnings, design. With a file format, ExportedFile: exportId, designId, revision, mode, format, url, expiresAt, filename, bytes, warnings, design. The types follow format.

render(input) → RenderedDesign​

Input
docRequired. A design document you hold.
designIdOptional. Its id: a popup's handle and a form's event carry it.
merge, textAs for designs.export.

The fields of ExportedDesign without exportId, designId and revision: nothing is recorded.

users.erase(userId) → void​

Erases one person and everything they made. Resolves when the erasure is under way. Erasure and privacy

verifyWebhook(rawBody, signature, secret, options?) → WebhookEvent​

Argument
rawBodyThe request body as a string, exactly as it arrived
signatureThe Lettrove-Signature header
secretThe webhook's signing secret (whsec_…)
options.toleranceSecondsHow old a delivery may be; default 300

Throws LettroveApiError with code signature_invalid when the signature does not match, the body was changed, or the delivery is too old. Webhooks

LettroveApiError​

Field
codeA stable error code
messageWhat happened
statusThe HTTP status, or 0 when Lettrove could not be reached (network_error)
requestIdQuote it to support
retryAfterSeconds to wait, when rate_limited
docsUrlThe code's row in Error codes, for your logs