furō Morfee

The API

Everything the builder can do, the API can do. The builder is no more than a shell around it, so you can drive the whole tool from another system.

Authentication

Every call needs an API key. Create one on API keys and send it along, in either header; both work:

X-Api-Key: mrf_a1b2c3_...
Authorization: Bearer mrf_a1b2c3_...

A key belongs to exactly one organization and grants access to nothing outside it. If it is missing or revoked, you get 401.

Endpoints

MethodPathWhat
GET/api/statusIs the service up, which PDF engine is running, and how is the queue doing.
GET/api/templatesEvery template in your organization. Filter on name with ?search=.
GET/api/templates/{id}One template, including its source, sample JSON and bindings.
POST/api/templatesSave or update a template. Trial-rendered against your sample JSON first.
POST/api/templates/{id}/copyMake a copy, with an id of its own.
DELETE/api/templates/{id}Delete a template. Calls on that id fail afterwards.
POST/api/renderThe real work: a template plus data returns a PDF.
GET/api/usageYour plan, your limits and what you have used this month.
POST/mcpThe MCP server. See the MCP page.

Making a PDF

POST https://morfee.furo.solutions/api/render
X-Api-Key: mrf_...
Content-Type: application/json

{
  "templateId": "quote-a3f9c1",
  "data": { "customer": { "name": "Van Dommelen Buitenleven" }, "lines": [ ... ] },
  "filename": "Quote 2026-0148.pdf"
}

You get the PDF bytes back, with Content-Type: application/pdf. Three variants through the format query parameter:

?format=pdfthe default: the bytes themselves
?format=urlJSON with a download URL, valid for an hour. Easier in Power Automate
?format=htmlthe rendered document without the PDF step, useful for checking

If you would rather send a flat payload, leave out data and send the fields themselves. Everything but templateId, filename and format then becomes the data.

Saving a template without the builder

The builder turns your HTML and your bindings into a Handlebars template. If you already have one, or you want to push a template from another system, send it straight in:

POST https://morfee.furo.solutions/api/templates
{
  "name": "Quote",
  "hbs": "<!doctype html>...{{text customer.name}}...",
  "sample": { "customer": { "name": "Van Dommelen" } },
  "bindings": [],
  "source": "<!doctype html>..."
}

The template is trial-rendered against your sample JSON first. If it does not render it is not stored, and you are told why. Send id along to update an existing one.

Error codes

400something is wrong with your request, and it says what
401no key, or a revoked one
402you are at the limit of your plan
404that template does not exist, or is not yours
502the rendering itself went wrong
503the render queue is full, or your request waited too long

Power Automate

Use the HTTP action with ?format=url, then you never have to drag binary content through your flow:

Method  : POST
URI     : https://morfee.furo.solutions/api/render?format=url
Headers : { "X-Api-Key": "mrf_...", "Content-Type": "application/json" }
Body    : { "templateId": "quote-a3f9c1", "data": @{outputs('Compose_the_data')} }

The response holds url, filename and bytes. Put a second HTTP action behind it (GET on that URL) to fetch the bytes, or hand the URL to whoever has to download it.