Emails

Design emails with your agent

Let Codex or Claude design complete emails and images, then review and confirm.

The fastest way to a great Audryo email is often not the editor. Open Codex, Claude Code, or Cursor, give it your brand and a brief, and let it design the whole email — copy, layout, and custom images — then hand the result to Audryo as a draft you review and publish.

Audryo does the parts an agent should not improvise: rendering to cross-client HTML, lint, the legal footer, unsubscribe links, consent, and delivery through your ESP.

When to use this

SituationBest tool
A new campaign, launch, or a whole onboarding seriesYour agent — it can write, design, and generate images in one pass
Custom illustrations or hero imagesYour agent with an image skill such as $image-gen
Five Journey emails × two languagesYour agent — it loops over every node and locale
Fix a typo, swap a button, adjust spacingThe editor
A quick rewrite of the open draftAsk AI in the editor

Whatever route you take, the result is the same message document, and it opens in the editor for final touches.

What you need

  1. Audryo connected to your agent through the hosted MCP server (https://mcp.audryo.com/mcp), with Read and Draft and set up access. Leave Send and go live off — the agent should not be able to send. See the Agent quickstart; for headless use, an API key with read and write works too.
  2. For custom images only: the hosted server has no upload tool yet. Either upload them yourself in Data → Content and let the agent use their URLs, or give a headless agent an API key with write for step 3.
  3. Recommended: the Audryo skills (npx skills add audryo/agent-toolkit), so the agent already knows the document rules below.
  4. Optional: an image generation skill (for example $image-gen in Codex) if you want custom visuals instead of product screenshots.

The workflow

1. Load brand and context

Ask the agent to read the project before it writes anything:

  • GET /projects/{projectId}/message_context — brand kit (logo, colors, fonts) and existing emails
  • Confirmed Foundation facts — the only product claims the email may make
  • GET /projects/{projectId}/message_templates — the brand base and lifecycle layouts, a good structural reference

2. Learn the document shape from a real email

Emails are stored as structured JSON blocks, not raw HTML. The most reliable way for an agent to learn the shape is to create a starter and read it back:

curl
npx audryo emails create --title "Autumn launch" --subject "Meet the new dashboard" --locale en

Then GET /projects/{projectId}/message_documents/{messageId}. The starter already contains your logo, heading, paragraph, button, and footer blocks with the correct attributes. The agent edits that tree instead of inventing one.

Supported blocks include heading, paragraph, button, image, logo, section, columns / column, spacer, horizontalRule, blockquote, lists, codeBlock, repeat, and footer. Merge tags are variable nodes inside text.

3. Generate and upload images

If the agent creates images, they must be uploaded before use, over HTTP with an API key (or by you in Data → Content):

curl
curl -X POST "$AUDRYO_API_BASE/projects/$AUDRYO_PROJECT_ID/project_assets" \
  -H "Authorization: Bearer $AUDRYO_API_KEY" \
  -F "file=@hero.png" \
  -F "altText=The new analytics dashboard on a laptop"

The response contains a durable URL. Put that URL into the image block's attrs.src.

  • PNG, JPEG, GIF, or WebP, up to 5 MB. SVG is not accepted — many email clients cannot display it.
  • Export at 2× the display width (a 600 px wide hero → 1200 px file). New uploads automatically get an optimized delivery copy, with a maximum 1600 px longest edge and no upscaling. JPEG/WebP use quality 85; PNG keeps transparency and uses lossless compression. Originals are retained, and a copy is used only when smaller. GIFs, animated images, and images above 40 megapixels stay unchanged. Existing assets and their URLs are unchanged.
  • Always pass meaningful altText. Many clients block images by default.
  • Never put the headline, price, or call to action only inside an image. It disappears when images are blocked and is invisible to screen readers.
  • For icons, use bundled audryo-icon: sources (GET /email_icons) instead of generating tiny images.

4. Render and iterate before saving

POST /projects/{projectId}/message_documents/draft_preview renders an unsaved draft and returns the final html, plainText, and lint findings. Nothing is stored.

On the hosted MCP server, use preview_email_draft with the same fields instead of calling the endpoint directly. It returns the render result and an inline MCP App in supporting clients, including desktop/mobile and plain-text views. Use preview_email with messageId after saving or revising a proposal. Other clients receive the same render data, with an Audryo link for saved previews. No preview operation saves or sends anything. See Connect your agent.

This is the design loop: the agent renders, looks at the HTML (or a screenshot of it at 600 px and 375 px), fixes lint findings, and repeats until the email is clean.

5. Save as a proposal

  • Standalone email or campaign: POST /message_documents with the authored content. It is saved as proposed.
  • Journey email: POST /message_proposals with workflowId, workflowNodeId, locale, subject, and content — once per email node and per enabled language.

Journey proposals preserve your block order and copy. Send the flat EmailLayout block map with at most 24 top-level blocks and exact uploaded image URLs. Invalid blocks, references, links, merge tags, or unknown images return 422 with field pointers and reasons; they are never silently removed or replaced.

Before editing an existing email, read GET /message_documents/{id} and pass its revisionToken as message.expectedRevision to POST /message_documents/{id}/revision. A quoted If-Match header is also accepted. Missing preconditions return 428. A stale draft or newer sibling returns 409 with latestMessageId; read that version and reconcile your edits before trying again. Never retry by blindly substituting a fresh token over old content.

For recipient previews, send contactId and optional dataVariables to the saved message's /preview endpoint or /message_documents/draft_preview. The same context is accepted by /test_deliveries. For a draft based on a saved email, include messageId to retain its Journey and system-email context. Contact fields, event variables, conditions and repeat blocks are evaluated as at delivery time. missingValues lists visible contact/data tokens with no value or fallback; unresolvedVariables lists tokens still present after personalization. Preview links are inert and previews never change the contact or save your draft.

6. Test, review, publish

The agent may send a test to your own inbox (POST .../test_deliveries, up to 10 recipients). Then you open the email in Audryo, make final edits, and click Publish. Publishing is a human decision; an agent should never set status: "confirmed" unless you asked it to.

In sandbox mode the agent can go one step further: start the journey, trigger it, call fast_forward_journey, and read the results with list_sandbox_messages and get_sandbox_message — every email checked end to end, with nobody receiving anything.

A prompt that works

text
Design the Audryo launch email for our new analytics dashboard.

Project: <PROJECT_ID>. Use the Audryo MCP tools.
1. Read message_context and the active Foundation revision. Only claim
   what those facts support.
2. Create a starter email and read it back to learn the block format.
3. Generate one hero image with $image-gen: 1200×600, our brand colors,
   no text in the image. Upload it as a project asset with alt text.
4. Write: subject (under 50 characters), preheader that adds to the
   subject, one heading, two short paragraphs, three benefit rows, one
   button to https://app.example.com/analytics.
5. Render with draft_preview, fix every lint finding, check it at mobile
   width.
6. Save as a proposed document and send a test to me@example.com.
Do not publish, schedule, or send to customers.

Rules the renderer enforces

RuleWhy
At least four blocks, including a heading, a button, and a footerScannable, actionable, and compliant
Button URLs are real https linksPlaceholder links such as https://example.com or # fail lint
Image src is a project asset or audryo-icon:Hotlinked images break or disappear later
Preheader is 1–180 charactersIt is the second line in the inbox preview
Merge tags use valid syntax, including fallbacksBroken filters fail lint instead of showing up in the inbox
No unsubscribe link in the contentAudryo adds it at send time in the footer

Copy and design checklist

  • One email, one job. One primary button. Secondary links stay quiet.
  • Subject: specific and honest, ideally under 50 characters. The preheader continues the thought rather than repeating it.
  • Mobile first: more than half of opens happen on phones. Short paragraphs, a button that is easy to tap, single-column on small screens.
  • Contrast: check text and button colors against the background.
  • Personalization with fallbacks: never send "Hi ,". See Personalization.
  • Every language: German copy runs about 30 % longer. Re-check layout in each locale. See Localization.