Start from a preset or your brand
Presets
GET /v1/themes/presets lists five starting points: Tendr default, Fashion, Gaming, Nonprofit and Minimal. Create a theme from one with from: { "preset": "fashion" }.Your website
POST /v1/themes/from-website reads your site’s name, logo and colours and saves a draft theme.Your WooCommerce store
POST /v1/themes/from-store builds a draft from the brand your connected store sent. Plugin 0.2.0 sends it when you connect and on Refresh brand from my store.Another theme
from: { "theme_id": "..." } copies a theme’s draft.BRAND_FETCH_FAILED and details.reason says why.
A theme document
A theme has adraft and, after publishing, a published copy. Both are the same document:
Settings
Every palette must be readable. Tendr checks the colours with the WCAG contrast formula: text on background and text on surface need at least 4.5 to 1, and the accent on background needs at least 3 to 1. A palette that fails is refused on save with a message that names the pair.
Light, dark and auto
Withauto, the shopper’s device decides. The page, its native controls and Tendr’s own warning, error and timer colours follow the palette’s background: a background darker than a luminance of 0.4 gets Tendr’s dark state colours, anything lighter gets the light ones.
Fonts
Choose a curated font from this list: Inter, DM Sans, Manrope, Plus Jakarta Sans, Space Grotesk, Outfit, Sora, Instrument Sans, Bricolage Grotesque, Playfair Display, Cormorant Garamond, Lora, Fraunces, DM Serif Display and JetBrains Mono. Or upload your own.woff2 file of up to 500 KB.
Your font styles your own blocks. Inside the payment block a curated font styles only its headings and the Pay button label. An uploaded font never applies there.
Blocks
A page is a list of blocks inblocks, and the thank-you page is a list in success_blocks. A page holds at most 40 blocks, with 2 levels of nesting, and every block needs a unique id of lowercase letters, digits and hyphens.
Any block can set
hidden: true. columns and section can hold any block above except payment, thank_you, back_to_store, columns and section.
Order summary and line items
When you create a session withline_items, the order_summary block lists them: name, quantity, unit price and an optional image. See checkout sessions. Names that look like a wallet address are masked, and product images are fetched, checked, re-encoded and served by Tendr, never hot-linked.
The sealed payment block
Thepayment block is Tendr’s. It holds the amount, the payee line, the token and network choice, the Pay button, the address and QR, warnings, timers, errors and status, the refund promise and the hold notice.
A theme cannot select, cover, move or restyle it, and nothing in a theme can change its words:
- The payee line reads “You’re paying your account name”. If your display name differs from your account name, a second line reads “account name · trading as display name”.
- Amounts, addresses, the QR caption, warnings, errors and timers always use Tendr’s fonts. Addresses use Tendr’s monospace font.
- Warning, error, success and timer colours are Tendr’s fixed light and dark values, never your palette.
- No theme can add a form, input, button, select or editable text anywhere on the page.
The Pay button words
button_label sets the words on the main Pay button only: the Pay button on the link page, the main wallet Pay button in the checkout and in previews. Secondary buttons keep Tendr’s words. Leave it unset for the default wording.
The label can contain {amount}, which Tendr replaces with the real, formatted amount. It cannot contain numbers, currency symbols, currency codes or any other {...} placeholder, so a theme can never state a different price.
Words Tendr writes
Tendr’s own words, such as “You’re paying”, warnings and errors, stay in English until the languages project ships. A theme’slanguage applies to your own text.
Preview, publish and make default
Edit freely.PATCH /v1/themes/:id saves the draft. Live shoppers keep seeing the published copy.
Validate. POST /v1/themes/validate checks a document and returns problems with a path and a plain message for each, without saving. Use it to show problems as the merchant types.
Preview. POST /v1/themes/:id/preview with sample (checkout or link), scheme (light or dark) and viewport (phone or desktop) returns a link that renders your draft with sample data. The link works for 15 minutes without sign-in, is never cached or indexed, and never creates a session.
Publish. POST /v1/themes/:id/publish copies the draft to the published version and bumps version. Make default. POST /v1/themes/:id/default sets the theme used when a session or link names none.
Publishing and changing the default affect live shoppers, so they need:
- a live secret key, or
- a dashboard user with
settings:managewho has done a recent step-up check.
403 FORBIDDEN. Everything else (drafts, uploads, previews, validation and brand pulls) works with test keys.
Which theme a shopper sees
An open test session picks up draft edits after a reload. If a live theme is republished while a shopper is mid-payment, their next refresh shows the new look and nothing else changes: the amount, address, timer and status stay the same.
If a theme is missing, invalid or cannot be read at render time, the page falls back to the Tendr default theme. A theme never stops a payment.

