We are in official beta.

Cross-Format

Search/replace across formats, image replacement, and HTTP proxy

8 endpoints in this category. All require X-API-Key header.


Search & Replace Text

POST /api/SearchReplaceText 1 token

Find and replace text across document formats (DOCX, XLSX, TXT). Auto-detects format.

Parameters
NameTypeRequiredDescription
file string required Base64-encoded file
replacements array required Array of {find, replace} or object {find: replace}
format string optional docx, xlsx, txt (auto-detect if omitted)
Request Example
JSON
{"file": "<base64-file>", "replacements": [{"find": "old", "replace": "new"}]}
Response Example
JSON
{"file": "UEsDBBQAAAA...", "replacementCount": 3, "format": "docx"}
Code Examples
curl -X POST "https://api.docbutterfly.com/api/SearchReplaceText" \
  -H "X-API-Key: df_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{"file": "<base64-file>", "replacements": [{"find": "old", "replace": "new"}]}'
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-API-Key", "df_your_api_key_here");

var json = @"{""file"": ""<base64-file>"", ""replacements"": [{""find"": ""old"", ""replace"": ""new""}]}";
var content = new StringContent(json, System.Text.Encoding.UTF8, "application/json");

var response = await client.PostAsync("https://api.docbutterfly.com/api/SearchReplaceText", content);
response.EnsureSuccessStatusCode();

var result = await response.Content.ReadAsStringAsync();
Console.WriteLine(result);
import requests
import json

url = "https://api.docbutterfly.com/api/SearchReplaceText"
headers = {
    "X-API-Key": "df_your_api_key_here",
    "Content-Type": "application/json"
}
payload = json.loads('{"file": "<base64-file>", "replacements": [{"find": "old", "replace": "new"}]}')

response = requests.post(url, headers=headers, json=payload)
response.raise_for_status()

data = response.json()
print(json.dumps(data, indent=2))
┌─────────────────────────────────────────────┐
│  Power Automate - HTTP Action               │
├─────────────────────────────────────────────┤
│                                             │
│  Method:  POST                              │
│  URI:     https://api.docbutterfly.com/api/SearchReplaceText
│                                             │
│  Headers:                                   │
│    X-API-Key:    df_your_api_key_here       │
│    Content-Type: application/json           │
│                                             │
│  Body:                                      │
│    {
│      "file": "\u003Cbase64-file\u003E",
│      "replacements": [
│        {
│          "find": "old",
│          "replace": "new"
│        }
│      ]
│    }
│                                             │
└─────────────────────────────────────────────┘

Steps:
1. Add an HTTP action to your flow
2. Set Method to "POST"
3. Set URI to "https://api.docbutterfly.com/api/SearchReplaceText"
4. Add the headers shown above
5. Paste the Body JSON into the Body field
6. Replace placeholder values with dynamic content as needed
Try in Testbed

Replace Text with Image

POST /api/ReplaceTextWithImage 2 tokens

Replace a placeholder tag in a DOCX with an inline image.

Parameters
NameTypeRequiredDescription
file string required Base64-encoded DOCX
placeholder string required Text to find e.g. {logo}
image string required Base64-encoded image
width number optional Width in cm (default: 5)
height number optional Height in cm (default: 5)
Request Example
JSON
{"file": "<base64-docx>", "placeholder": "{logo}", "image": "<base64-image>", "width": 5, "height": 3}
Response Example
JSON
{"file": "UEsDBBQAAAA..."}
Code Examples
curl -X POST "https://api.docbutterfly.com/api/ReplaceTextWithImage" \
  -H "X-API-Key: df_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{"file": "<base64-docx>", "placeholder": "{logo}", "image": "<base64-image>", "width": 5, "height": 3}'
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-API-Key", "df_your_api_key_here");

var json = @"{""file"": ""<base64-docx>"", ""placeholder"": ""{logo}"", ""image"": ""<base64-image>"", ""width"": 5, ""height"": 3}";
var content = new StringContent(json, System.Text.Encoding.UTF8, "application/json");

var response = await client.PostAsync("https://api.docbutterfly.com/api/ReplaceTextWithImage", content);
response.EnsureSuccessStatusCode();

var result = await response.Content.ReadAsStringAsync();
Console.WriteLine(result);
import requests
import json

url = "https://api.docbutterfly.com/api/ReplaceTextWithImage"
headers = {
    "X-API-Key": "df_your_api_key_here",
    "Content-Type": "application/json"
}
payload = json.loads('{"file": "<base64-docx>", "placeholder": "{logo}", "image": "<base64-image>", "width": 5, "height": 3}')

response = requests.post(url, headers=headers, json=payload)
response.raise_for_status()

data = response.json()
print(json.dumps(data, indent=2))
┌─────────────────────────────────────────────┐
│  Power Automate - HTTP Action               │
├─────────────────────────────────────────────┤
│                                             │
│  Method:  POST                              │
│  URI:     https://api.docbutterfly.com/api/ReplaceTextWithImage
│                                             │
│  Headers:                                   │
│    X-API-Key:    df_your_api_key_here       │
│    Content-Type: application/json           │
│                                             │
│  Body:                                      │
│    {
│      "file": "\u003Cbase64-docx\u003E",
│      "placeholder": "{logo}",
│      "image": "\u003Cbase64-image\u003E",
│      "width": 5,
│      "height": 3
│    }
│                                             │
└─────────────────────────────────────────────┘

Steps:
1. Add an HTTP action to your flow
2. Set Method to "POST"
3. Set URI to "https://api.docbutterfly.com/api/ReplaceTextWithImage"
4. Add the headers shown above
5. Paste the Body JSON into the Body field
6. Replace placeholder values with dynamic content as needed
Try in Testbed

HTTP Request

POST /api/HttpRequest 1 token

Make an HTTP request to an external URL. Blocks private/internal IPs.

Parameters
NameTypeRequiredDescription
url string required Target URL
method string optional GET, POST, PUT, DELETE, PATCH (default: GET)
headers object optional Request headers
body string optional Request body
timeout number optional Timeout in ms (max 30000) (default: 30000)
Request Example
JSON
{"url": "https://httpbin.org/get", "method": "GET"}
Response Example
JSON
{"statusCode": 200, "headers": {"content-type": "application/json"}, "body": "..."}
Code Examples
curl -X POST "https://api.docbutterfly.com/api/HttpRequest" \
  -H "X-API-Key: df_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://httpbin.org/get", "method": "GET"}'
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-API-Key", "df_your_api_key_here");

var json = @"{""url"": ""https://httpbin.org/get"", ""method"": ""GET""}";
var content = new StringContent(json, System.Text.Encoding.UTF8, "application/json");

var response = await client.PostAsync("https://api.docbutterfly.com/api/HttpRequest", content);
response.EnsureSuccessStatusCode();

var result = await response.Content.ReadAsStringAsync();
Console.WriteLine(result);
import requests
import json

url = "https://api.docbutterfly.com/api/HttpRequest"
headers = {
    "X-API-Key": "df_your_api_key_here",
    "Content-Type": "application/json"
}
payload = json.loads('{"url": "https://httpbin.org/get", "method": "GET"}')

response = requests.post(url, headers=headers, json=payload)
response.raise_for_status()

data = response.json()
print(json.dumps(data, indent=2))
┌─────────────────────────────────────────────┐
│  Power Automate - HTTP Action               │
├─────────────────────────────────────────────┤
│                                             │
│  Method:  POST                              │
│  URI:     https://api.docbutterfly.com/api/HttpRequest
│                                             │
│  Headers:                                   │
│    X-API-Key:    df_your_api_key_here       │
│    Content-Type: application/json           │
│                                             │
│  Body:                                      │
│    {
│      "url": "https://httpbin.org/get",
│      "method": "GET"
│    }
│                                             │
└─────────────────────────────────────────────┘

Steps:
1. Add an HTTP action to your flow
2. Set Method to "POST"
3. Set URI to "https://api.docbutterfly.com/api/HttpRequest"
4. Add the headers shown above
5. Paste the Body JSON into the Body field
6. Replace placeholder values with dynamic content as needed
Try in Testbed

REST Request

POST /api/RestRequest 1 token

Call any REST API through a saved connection — the credential lives in the connection, never in the request. Source and destination: GET to read, POST/PUT/PATCH to write. Supports bearer, basic, API-key header, and OAuth2 client-credentials.

PAGINATION (#1496) IS OPT-IN AND OFF BY DEFAULT — with no "paginate" block the behavior is exactly one request and one response, and no "pagination" field comes back. With it, the response instead carries items (or pages) plus pagination: { mode, pagesRequested, pagesFetched, itemCount, bytesFetched, elapsedMs, stopReason }. stopReason is always present and is one of exhausted, cap, bytes, time, loop, refused, httpError or transport — a truncated result that LOOKS complete is worse than an error, so branch on that field rather than on the count. N pages is still ONE token: the aggregate byte ceiling equals the single-response ceiling, so a paginated call cannot return more data than a single call already could, and pagination.pagesRequested reports exactly how many outbound calls your one billed call made. Every page URL is re-checked against the SSRF guard and pinned to the connection's origin, because a next-link is remote-controlled input — an API answering with a link to the instance metadata endpoint, or to another host, terminates the walk with stopReason "refused" and returns the pages already collected.
Parameters
NameTypeRequiredDescription
connectionId string required A registry connection of type "rest"
path string optional Path appended under the connection's baseUrl (or an absolute URL on the same origin)
method string optional GET, POST, PUT, PATCH, DELETE, HEAD (default: GET)
query object optional Query string values; an array value repeats the key
headers object optional Extra request headers. Authorization is owned by the connection and cannot be overridden
body string optional Request body — an object is sent as JSON. Provide this OR contentBase64
contentBase64 string optional Binary request body as base64 (max 5MB decoded). Provide this OR body
timeout number optional Timeout in ms (max 30000) (default: 30000)
paginate object optional Follow the API's own paging and return the whole walk in one call. GET only. { mode: "link" | "cursor" | "nextUrl" | "offset", itemsPath?, maxPages? (default 10, max 50), maxBytes? (default and max 5MB aggregate), maxMs? (default 60000, max 120000) } plus per-mode keys: cursor takes cursorPath, cursorParam and optional hasMorePath; nextUrl takes nextUrlPath; offset takes limitParam, offsetParam, pageSize and optional startOffset; link needs none. Omit the block entirely for the single-request behavior
Request Example
JSON
{"connectionId": "conn_1a2b3c…", "path": "orders", "method": "GET", "query": {"limit": 10}}
Response Example
JSON
{"success": true, "statusCode": 200, "ok": true, "headers": {"content-type": "application/json"}, "contentType": "application/json", "body": "...", "url": "https://api.example.com/v1/orders", "timing": {"total": 512}}
Code Examples
curl -X POST "https://api.docbutterfly.com/api/RestRequest" \
  -H "X-API-Key: df_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{"connectionId": "conn_1a2b3c…", "path": "orders", "method": "GET", "query": {"limit": 10}}'
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-API-Key", "df_your_api_key_here");

var json = @"{""connectionId"": ""conn_1a2b3c…"", ""path"": ""orders"", ""method"": ""GET"", ""query"": {""limit"": 10}}";
var content = new StringContent(json, System.Text.Encoding.UTF8, "application/json");

var response = await client.PostAsync("https://api.docbutterfly.com/api/RestRequest", content);
response.EnsureSuccessStatusCode();

var result = await response.Content.ReadAsStringAsync();
Console.WriteLine(result);
import requests
import json

url = "https://api.docbutterfly.com/api/RestRequest"
headers = {
    "X-API-Key": "df_your_api_key_here",
    "Content-Type": "application/json"
}
payload = json.loads('{"connectionId": "conn_1a2b3c…", "path": "orders", "method": "GET", "query": {"limit": 10}}')

response = requests.post(url, headers=headers, json=payload)
response.raise_for_status()

data = response.json()
print(json.dumps(data, indent=2))
┌─────────────────────────────────────────────┐
│  Power Automate - HTTP Action               │
├─────────────────────────────────────────────┤
│                                             │
│  Method:  POST                              │
│  URI:     https://api.docbutterfly.com/api/RestRequest
│                                             │
│  Headers:                                   │
│    X-API-Key:    df_your_api_key_here       │
│    Content-Type: application/json           │
│                                             │
│  Body:                                      │
│    {
│      "connectionId": "conn_1a2b3c\u2026",
│      "path": "orders",
│      "method": "GET",
│      "query": {
│        "limit": 10
│      }
│    }
│                                             │
└─────────────────────────────────────────────┘

Steps:
1. Add an HTTP action to your flow
2. Set Method to "POST"
3. Set URI to "https://api.docbutterfly.com/api/RestRequest"
4. Add the headers shown above
5. Paste the Body JSON into the Body field
6. Replace placeholder values with dynamic content as needed
Try in Testbed

Compose Fill

POST /api/ComposeFill 1 token

Fill a docx/pdf/xlsx/pptx/html template in one call — inline (base64 + kind) or by saved templateId. Returns the filled document plus a dataHash for dedupe.

Saved templates built with the Template Generator are HTML and support repeating sections plus contract-declared formatting (currency/date/number). Add outputFormat:"pdf" to get a rendered PDF. No contract field is mandatory — a key left out of the payload renders blank and is reported in unresolvedFields. CODED VALUES: send the code your system stores ("needs_replacement", a Dataverse optionset integer) — never pre-format it. A saved template decodes it from the code/label list held in its contract. An inline template has no stored contract, so put the list in the payload: {"data": {"filter_condition": "needs_replacement", "__choices": {"filter_condition": {"needs_replacement": "Needs replacement (part on order)"}}}}. __choices is read at the top level only, is never rendered or reported as a field, and accepts [{value,label}], [{value,text}] or a compact {code: label} map. A code with no entry is de-slugged ("Needs Replacement") rather than printed raw, so adding an option upstream degrades readably instead of breaking a running pipeline.
Parameters
NameTypeRequiredDescription
template string optional Base64 template (one-off). Provide this OR templateId
templateId string optional Saved template id — a Template Generator (HTML) template, or a PDF AcroForm template. Provide this OR template
kind string optional docx, pdf, xlsx, pptx, html (required for inline)
data object required Merge data: {key: value}. May carry a reserved "__choices" block mapping a field (or a repeating-section column) to its code/label list — see notes
outputFormat string optional native or pdf (pdf only for html kind, Linux)
pageSize string optional Named paper size — see the paper-size table on the API reference overview. Case- and punctuation-insensitive; aliases such as "US Letter" are accepted. Via raw JSON a custom size object is also accepted: {"width": n, "height": n, "units": "pt|px|in|mm|cm"} (units default pt; 1-14400pt / 200in per side). An unknown size, unit, or orientation returns 400 — nothing silently falls back. Applies to PDF output (outputFormat "pdf" or an HTML saved template rendered to PDF); legacy key paperSize is still accepted (default: Letter)
orientation string optional Page orientation. "landscape" puts the long edge horizontal. Omit to keep the size's own orientation (portrait for every named size except Ledger)
flatten boolean optional Flatten PDF form fields (default: false)
filename string optional Output filename (no extension) (default: result)
Request Example
JSON
{"template": "<base64-docx>", "kind": "docx", "data": {"name": "Jamie"}}
Response Example
JSON
{"success": true, "kind": "docx", "file": "UEsDBBQAAAA...", "contentType": "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "ext": "docx", "filename": "result.docx", "dataHash": "<sha256>"}
Code Examples
curl -X POST "https://api.docbutterfly.com/api/ComposeFill" \
  -H "X-API-Key: df_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{"template": "<base64-docx>", "kind": "docx", "data": {"name": "Jamie"}}'
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-API-Key", "df_your_api_key_here");

var json = @"{""template"": ""<base64-docx>"", ""kind"": ""docx"", ""data"": {""name"": ""Jamie""}}";
var content = new StringContent(json, System.Text.Encoding.UTF8, "application/json");

var response = await client.PostAsync("https://api.docbutterfly.com/api/ComposeFill", content);
response.EnsureSuccessStatusCode();

var result = await response.Content.ReadAsStringAsync();
Console.WriteLine(result);
import requests
import json

url = "https://api.docbutterfly.com/api/ComposeFill"
headers = {
    "X-API-Key": "df_your_api_key_here",
    "Content-Type": "application/json"
}
payload = json.loads('{"template": "<base64-docx>", "kind": "docx", "data": {"name": "Jamie"}}')

response = requests.post(url, headers=headers, json=payload)
response.raise_for_status()

data = response.json()
print(json.dumps(data, indent=2))
┌─────────────────────────────────────────────┐
│  Power Automate - HTTP Action               │
├─────────────────────────────────────────────┤
│                                             │
│  Method:  POST                              │
│  URI:     https://api.docbutterfly.com/api/ComposeFill
│                                             │
│  Headers:                                   │
│    X-API-Key:    df_your_api_key_here       │
│    Content-Type: application/json           │
│                                             │
│  Body:                                      │
│    {
│      "template": "\u003Cbase64-docx\u003E",
│      "kind": "docx",
│      "data": {
│        "name": "Jamie"
│      }
│    }
│                                             │
└─────────────────────────────────────────────┘

Steps:
1. Add an HTTP action to your flow
2. Set Method to "POST"
3. Set URI to "https://api.docbutterfly.com/api/ComposeFill"
4. Add the headers shown above
5. Paste the Body JSON into the Body field
6. Replace placeholder values with dynamic content as needed
Try in Testbed

Analyze Template Data

POST /api/AnalyzeTemplateData 1 token

Flatten a sample JSON or XML payload into a field contract: dot-paths, inferred datatypes, sample values, and arrays promoted to repeating tables. No AI, no document required.

Datatypes are inferred from the value plus the key name (a number under a key like total/amount/price becomes currency). XML lists are only detected as repeating tables when the sample contains two or more of the same element — include at least two rows. Inference never guesses that a value is a coded choice — "rooftop_unit" and a part number are indistinguishable from the value alone, and a wrong guess would rewrite real data. Supply the list via dataDefinition, choices, or a __choices block inside the sample itself, and those fields come back as dataType "choice" with an options table that the fill engine uses for every later ComposeFill.
Parameters
NameTypeRequiredDescription
data object optional Sample payload as JSON. Provide this OR dataXml
dataXml string optional Sample payload as XML. Provide this OR data
maxDepth number optional Maximum nesting depth to map (default: 6)
dataDefinition object optional The source system's form/optionset definition, pasted whole (SurveyJS or Dynamics Field Service shape). Any question with a choices list becomes a choice field so the document shows the label, not the code
choices object optional Explicit code/label lists: {fieldName: [{value, label}]}. Overrides dataDefinition and the payload's own __choices block
Request Example
JSON
{"data": {"invoice": {"number": "INV-1001", "issuedOn": "2026-07-28", "total": 1240.50, "paid": false}, "customer": {"name": "Acme Ltd", "email": "ap@acme.com"}, "lines": [{"description": "Consulting", "qty": 10, "amount": 100.00}, {"description": "License", "qty": 1, "amount": 240.50}]}}
Response Example
JSON
{"success": true, "source": "json", "fields": [{"name": "invoice.number", "label": "Number", "mode": "dynamic", "dataType": "string", "sample": "INV-1001"}, {"name": "invoice.issuedOn", "label": "Issued On", "dataType": "date", "format": {"dateStyle": "medium"}}, {"name": "invoice.total", "label": "Total", "dataType": "currency", "format": {"currency": "USD", "decimals": 2}}, {"name": "invoice.paid", "dataType": "boolean"}, {"name": "customer.email", "dataType": "email"}], "tables": [{"name": "lines", "label": "Lines", "columns": [{"name": "description", "dataType": "string"}, {"name": "qty", "dataType": "number"}, {"name": "amount", "dataType": "currency"}], "sampleRowCount": 2}], "inputContract": {"required": [], "optional": ["invoice.number", "invoice.issuedOn", "invoice.total", "invoice.paid", "customer.name", "customer.email"], "tables": [{"name": "lines", "columns": ["description", "qty", "amount"]}]}, "warnings": []}
Code Examples
curl -X POST "https://api.docbutterfly.com/api/AnalyzeTemplateData" \
  -H "X-API-Key: df_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{"data": {"invoice": {"number": "INV-1001", "issuedOn": "2026-07-28", "total": 1240.50, "paid": false}, "customer": {"name": "Acme Ltd", "email": "ap@acme.com"}, "lines": [{"description": "Consulting", "qty": 10, "amount": 100.00}, {"description": "License", "qty": 1, "amount": 240.50}]}}'
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-API-Key", "df_your_api_key_here");

var json = @"{""data"": {""invoice"": {""number"": ""INV-1001"", ""issuedOn"": ""2026-07-28"", ""total"": 1240.50, ""paid"": false}, ""customer"": {""name"": ""Acme Ltd"", ""email"": ""ap@acme.com""}, ""lines"": [{""description"": ""Consulting"", ""qty"": 10, ""amount"": 100.00}, {""description"": ""License"", ""qty"": 1, ""amount"": 240.50}]}}";
var content = new StringContent(json, System.Text.Encoding.UTF8, "application/json");

var response = await client.PostAsync("https://api.docbutterfly.com/api/AnalyzeTemplateData", content);
response.EnsureSuccessStatusCode();

var result = await response.Content.ReadAsStringAsync();
Console.WriteLine(result);
import requests
import json

url = "https://api.docbutterfly.com/api/AnalyzeTemplateData"
headers = {
    "X-API-Key": "df_your_api_key_here",
    "Content-Type": "application/json"
}
payload = json.loads('{"data": {"invoice": {"number": "INV-1001", "issuedOn": "2026-07-28", "total": 1240.50, "paid": false}, "customer": {"name": "Acme Ltd", "email": "ap@acme.com"}, "lines": [{"description": "Consulting", "qty": 10, "amount": 100.00}, {"description": "License", "qty": 1, "amount": 240.50}]}}')

response = requests.post(url, headers=headers, json=payload)
response.raise_for_status()

data = response.json()
print(json.dumps(data, indent=2))
┌─────────────────────────────────────────────┐
│  Power Automate - HTTP Action               │
├─────────────────────────────────────────────┤
│                                             │
│  Method:  POST                              │
│  URI:     https://api.docbutterfly.com/api/AnalyzeTemplateData
│                                             │
│  Headers:                                   │
│    X-API-Key:    df_your_api_key_here       │
│    Content-Type: application/json           │
│                                             │
│  Body:                                      │
│    {
│      "data": {
│        "invoice": {
│          "number": "INV-1001",
│          "issuedOn": "2026-07-28",
│          "total": 1240.50,
│          "paid": false
│        },
│        "customer": {
│          "name": "Acme Ltd",
│          "email": "ap@acme.com"
│        },
│        "lines": [
│          {
│            "description": "Consulting",
│            "qty": 10,
│            "amount": 100.00
│          },
│          {
│            "description": "License",
│            "qty": 1,
│            "amount": 240.50
│          }
│        ]
│      }
│    }
│                                             │
└─────────────────────────────────────────────┘

Steps:
1. Add an HTTP action to your flow
2. Set Method to "POST"
3. Set URI to "https://api.docbutterfly.com/api/AnalyzeTemplateData"
4. Add the headers shown above
5. Paste the Body JSON into the Body field
6. Replace placeholder values with dynamic content as needed
Try in Testbed

Generate Template from Data

POST /api/GenerateTemplateFromData 5 tokens

Turn a sample JSON or XML payload into a ready-to-edit HTML document template with placeholders and repeating sections. AI drafts the layout; falls back to a standard layout if AI is unavailable.

Generated HTML is sanitized before it is returned or stored — scripts, event handlers, external stylesheets/images and unsafe URL schemes are removed. Repeating-section markers are emitted wrapped in HTML comments so they survive inside <table> elements. Save the result with POST /api/manage/templates/{clientId}/compose, then fill it repeatedly with ComposeFill using the returned templateId — you pay this 5-token authoring cost once, and 1 token per document thereafter. Code/label lists supplied here (dataDefinition, choices, or a __choices block in the sample) are stored on the saved template's contract, so every later fill decodes the same way no matter which system posts the data.
Parameters
NameTypeRequiredDescription
data object optional Sample payload as JSON. Provide this OR dataXml
dataXml string optional Sample payload as XML. Provide this OR data
documentType string optional Hint for the layout, e.g. invoice, purchase order, statement
title string optional Document title
pageSize string optional Named paper size for the template's @page rule — any name from the paper-size table (no custom dimensions here; an unrecognized name falls back to Letter) (default: Letter)
extraFields array optional Custom fields to include: [{name, dataType, mode, value}]
useAi boolean optional Set false to skip AI and use the standard layout (default: true)
dataDefinition object optional The source system's form/optionset definition, pasted whole (SurveyJS or Dynamics Field Service shape). Questions with a choices list become choice fields, and the drafter is shown the decoded label rather than the code
choices object optional Explicit code/label lists: {fieldName: [{value, label}]}. Overrides dataDefinition and the payload's own __choices block
background object optional Page background: {image (data: or https:), color, opacity 0-1, fit: cover|contain|tile|stretch, showThrough: true to keep content elements' own background colors from hiding it}. When the template html already carries a background, omitted keys keep the designed values — opacity does not reset to 1
Request Example
JSON
{"dataXml": "<invoice><number>INV-1001</number><issuedOn>2026-07-28</issuedOn><total>1240.50</total><lines><line><description>Consulting</description><qty>10</qty><amount>100.00</amount></line><line><description>License</description><qty>1</qty><amount>240.50</amount></line></lines></invoice>", "documentType": "invoice", "title": "Invoice", "pageSize": "Letter", "extraFields": [{"name": "invoice.dueDate", "dataType": "date"}, {"name": "company.tagline", "mode": "static", "value": "Precision document automation"}]}
Response Example
JSON
{"success": true, "source": "xml", "engine": "ai", "html": "<!DOCTYPE html><html><head><style>@page{size:Letter;margin:18mm}...</style></head><body><h1>Invoice {{number}}</h1><table><tbody><!--{{#lines.line}}--><tr><td>{{description}}</td><td>{{qty}}</td><td>{{amount}}</td></tr><!--{{/lines.line}}--></tbody></table></body></html>", "fields": [], "tables": [], "inputContract": {"required": [], "optional": ["invoice.dueDate", "number", "issuedOn", "total"], "tables": [{"name": "lines.line", "columns": ["description", "qty", "amount"]}], "example": {}}, "placeholders": {"used": ["number", "total"], "unknown": [], "unused": []}, "warnings": []}
Code Examples
curl -X POST "https://api.docbutterfly.com/api/GenerateTemplateFromData" \
  -H "X-API-Key: df_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{"dataXml": "<invoice><number>INV-1001</number><issuedOn>2026-07-28</issuedOn><total>1240.50</total><lines><line><description>Consulting</description><qty>10</qty><amount>100.00</amount></line><line><description>License</description><qty>1</qty><amount>240.50</amount></line></lines></invoice>", "documentType": "invoice", "title": "Invoice", "pageSize": "Letter", "extraFields": [{"name": "invoice.dueDate", "dataType": "date"}, {"name": "company.tagline", "mode": "static", "value": "Precision document automation"}]}'
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-API-Key", "df_your_api_key_here");

var json = @"{""dataXml"": ""<invoice><number>INV-1001</number><issuedOn>2026-07-28</issuedOn><total>1240.50</total><lines><line><description>Consulting</description><qty>10</qty><amount>100.00</amount></line><line><description>License</description><qty>1</qty><amount>240.50</amount></line></lines></invoice>"", ""documentType"": ""invoice"", ""title"": ""Invoice"", ""pageSize"": ""Letter"", ""extraFields"": [{""name"": ""invoice.dueDate"", ""dataType"": ""date""}, {""name"": ""company.tagline"", ""mode"": ""static"", ""value"": ""Precision document automation""}]}";
var content = new StringContent(json, System.Text.Encoding.UTF8, "application/json");

var response = await client.PostAsync("https://api.docbutterfly.com/api/GenerateTemplateFromData", content);
response.EnsureSuccessStatusCode();

var result = await response.Content.ReadAsStringAsync();
Console.WriteLine(result);
import requests
import json

url = "https://api.docbutterfly.com/api/GenerateTemplateFromData"
headers = {
    "X-API-Key": "df_your_api_key_here",
    "Content-Type": "application/json"
}
payload = json.loads('{"dataXml": "<invoice><number>INV-1001</number><issuedOn>2026-07-28</issuedOn><total>1240.50</total><lines><line><description>Consulting</description><qty>10</qty><amount>100.00</amount></line><line><description>License</description><qty>1</qty><amount>240.50</amount></line></lines></invoice>", "documentType": "invoice", "title": "Invoice", "pageSize": "Letter", "extraFields": [{"name": "invoice.dueDate", "dataType": "date"}, {"name": "company.tagline", "mode": "static", "value": "Precision document automation"}]}')

response = requests.post(url, headers=headers, json=payload)
response.raise_for_status()

data = response.json()
print(json.dumps(data, indent=2))
┌─────────────────────────────────────────────┐
│  Power Automate - HTTP Action               │
├─────────────────────────────────────────────┤
│                                             │
│  Method:  POST                              │
│  URI:     https://api.docbutterfly.com/api/GenerateTemplateFromData
│                                             │
│  Headers:                                   │
│    X-API-Key:    df_your_api_key_here       │
│    Content-Type: application/json           │
│                                             │
│  Body:                                      │
│    {
│      "dataXml": "\u003Cinvoice\u003E\u003Cnumber\u003EINV-1001\u003C/number\u003E\u003CissuedOn\u003E2026-07-28\u003C/issuedOn\u003E\u003Ctotal\u003E1240.50\u003C/total\u003E\u003Clines\u003E\u003Cline\u003E\u003Cdescription\u003EConsulting\u003C/description\u003E\u003Cqty\u003E10\u003C/qty\u003E\u003Camount\u003E100.00\u003C/amount\u003E\u003C/line\u003E\u003Cline\u003E\u003Cdescription\u003ELicense\u003C/description\u003E\u003Cqty\u003E1\u003C/qty\u003E\u003Camount\u003E240.50\u003C/amount\u003E\u003C/line\u003E\u003C/lines\u003E\u003C/invoice\u003E",
│      "documentType": "invoice",
│      "title": "Invoice",
│      "pageSize": "Letter",
│      "extraFields": [
│        {
│          "name": "invoice.dueDate",
│          "dataType": "date"
│        },
│        {
│          "name": "company.tagline",
│          "mode": "static",
│          "value": "Precision document automation"
│        }
│      ]
│    }
│                                             │
└─────────────────────────────────────────────┘

Steps:
1. Add an HTTP action to your flow
2. Set Method to "POST"
3. Set URI to "https://api.docbutterfly.com/api/GenerateTemplateFromData"
4. Add the headers shown above
5. Paste the Body JSON into the Body field
6. Replace placeholder values with dynamic content as needed
Try in Testbed

Import HTML Template

POST /api/ImportHtmlTemplate 1 token

Bring your own HTML. Send a document you already have plus the JSON payload it was produced from, and get it back as a fill template: {{placeholders}} where the values were, a repeating section around the repeated block, and a field contract. Fill it repeatedly with ComposeFill.

A PLACEHOLDER IS ONLY WRITTEN WHERE THE FILL REPRODUCES THE ORIGINAL TEXT EXACTLY. Candidate placements are generated by running the renderer's own formatting over the value, so a figure the document printed in a form the renderer cannot regenerate — a truncated $562 where the renderer rounds to $563 — is left as literal text and reported in unbound, rather than silently changing a number on your document. verification.identical says whether the round trip matched, text node for text node. READ THE REPORT, NOT JUST THE TEMPLATE. unbound names values that are nowhere in the document or cannot round-trip; ambiguous names values that appear only inside a longer sentence and are too short to place without guessing; residualLiterals names values that WERE bound somewhere and still sit as literal text somewhere else — those spots will not follow the next payload and are the ones to mark by hand. The authored document is untrusted and is sanitized the same way a generated template is: script, iframe/object/embed, form controls, every on* handler, external stylesheets and unsafe URL schemes are removed, and remote url() is scrubbed out of <style>. That matters because the filled HTML is a document you publish, and a published page runs whatever script it carries. An interactive page loses its behavior here — the layout and the data survive, the scripting does not. Nothing here fetches a URL. Paste or upload the markup.
Parameters
NameTypeRequiredDescription
html string optional The authored document markup. Provide this OR htmlBase64. This is markup, never a URL — nothing here fetches
htmlBase64 string optional The same document, base64-encoded, for callers that would rather not escape it into JSON
data object required The payload the document was produced from. It is what the import matches the document's text against, and it becomes the field contract
sanitize boolean optional Remove script, event handlers, embedded frames and unsafe URL schemes from the authored document (default: true)
stripExternalReferences boolean optional Also remove https: images and other external references, which sanitizing keeps by default (default: false)
annotateForDesigner boolean optional Stamp the data-tg-* designer attributes a generated template carries, so the import is manageable in the Template Generator (default: false)
returnFilled boolean optional Return the template filled with the payload you supplied, as proof the fill reproduces the original (default: true)
Request Example
JSON
{"html": "<h1>Cedar Ridge Manufacturing</h1><p>Columbus, OH</p><table><tbody><tr><td>Marcus Handley</td><td>$525.00</td></tr><tr><td>Alina Petrova</td><td>$525.00</td></tr></tbody></table>", "data": {"employer": "Cedar Ridge Manufacturing", "city_state": "Columbus, OH", "roster": [{"name": "Marcus Handley", "allowance": 525.0}, {"name": "Alina Petrova", "allowance": 525.0}]}}
Response Example
JSON
{"success": true, "template": "<h1>{{employer}}</h1><p>{{city_state}}</p><table><tbody><!--{{#roster}}--><tr><td>{{name}}</td><td>{{allowance}}</td></tr><!--{{/roster}}--></tbody></table>", "bindings": [{"path": "employer", "occurrences": 1, "renderedAs": "Cedar Ridge Manufacturing", "dataType": "string"}], "tables": [{"path": "roster", "marked": true, "rowsCollapsed": 2, "columns": [{"name": "name", "dataType": "string"}, {"name": "allowance", "dataType": "currency", "format": {"currency": "USD", "decimals": 2}}]}], "unbound": [], "ambiguous": [], "residualLiterals": [], "sanitized": {"removed": [], "externalReferences": []}, "verification": {"identical": true, "substitutions": 6, "missing": []}, "filled": "<h1>Cedar Ridge Manufacturing</h1>..."}
Code Examples
curl -X POST "https://api.docbutterfly.com/api/ImportHtmlTemplate" \
  -H "X-API-Key: df_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{"html": "<h1>Cedar Ridge Manufacturing</h1><p>Columbus, OH</p><table><tbody><tr><td>Marcus Handley</td><td>$525.00</td></tr><tr><td>Alina Petrova</td><td>$525.00</td></tr></tbody></table>", "data": {"employer": "Cedar Ridge Manufacturing", "city_state": "Columbus, OH", "roster": [{"name": "Marcus Handley", "allowance": 525.0}, {"name": "Alina Petrova", "allowance": 525.0}]}}'
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-API-Key", "df_your_api_key_here");

var json = @"{""html"": ""<h1>Cedar Ridge Manufacturing</h1><p>Columbus, OH</p><table><tbody><tr><td>Marcus Handley</td><td>$525.00</td></tr><tr><td>Alina Petrova</td><td>$525.00</td></tr></tbody></table>"", ""data"": {""employer"": ""Cedar Ridge Manufacturing"", ""city_state"": ""Columbus, OH"", ""roster"": [{""name"": ""Marcus Handley"", ""allowance"": 525.0}, {""name"": ""Alina Petrova"", ""allowance"": 525.0}]}}";
var content = new StringContent(json, System.Text.Encoding.UTF8, "application/json");

var response = await client.PostAsync("https://api.docbutterfly.com/api/ImportHtmlTemplate", content);
response.EnsureSuccessStatusCode();

var result = await response.Content.ReadAsStringAsync();
Console.WriteLine(result);
import requests
import json

url = "https://api.docbutterfly.com/api/ImportHtmlTemplate"
headers = {
    "X-API-Key": "df_your_api_key_here",
    "Content-Type": "application/json"
}
payload = json.loads('{"html": "<h1>Cedar Ridge Manufacturing</h1><p>Columbus, OH</p><table><tbody><tr><td>Marcus Handley</td><td>$525.00</td></tr><tr><td>Alina Petrova</td><td>$525.00</td></tr></tbody></table>", "data": {"employer": "Cedar Ridge Manufacturing", "city_state": "Columbus, OH", "roster": [{"name": "Marcus Handley", "allowance": 525.0}, {"name": "Alina Petrova", "allowance": 525.0}]}}')

response = requests.post(url, headers=headers, json=payload)
response.raise_for_status()

data = response.json()
print(json.dumps(data, indent=2))
┌─────────────────────────────────────────────┐
│  Power Automate - HTTP Action               │
├─────────────────────────────────────────────┤
│                                             │
│  Method:  POST                              │
│  URI:     https://api.docbutterfly.com/api/ImportHtmlTemplate
│                                             │
│  Headers:                                   │
│    X-API-Key:    df_your_api_key_here       │
│    Content-Type: application/json           │
│                                             │
│  Body:                                      │
│    {
│      "html": "\u003Ch1\u003ECedar Ridge Manufacturing\u003C/h1\u003E\u003Cp\u003EColumbus, OH\u003C/p\u003E\u003Ctable\u003E\u003Ctbody\u003E\u003Ctr\u003E\u003Ctd\u003EMarcus Handley\u003C/td\u003E\u003Ctd\u003E$525.00\u003C/td\u003E\u003C/tr\u003E\u003Ctr\u003E\u003Ctd\u003EAlina Petrova\u003C/td\u003E\u003Ctd\u003E$525.00\u003C/td\u003E\u003C/tr\u003E\u003C/tbody\u003E\u003C/table\u003E",
│      "data": {
│        "employer": "Cedar Ridge Manufacturing",
│        "city_state": "Columbus, OH",
│        "roster": [
│          {
│            "name": "Marcus Handley",
│            "allowance": 525.0
│          },
│          {
│            "name": "Alina Petrova",
│            "allowance": 525.0
│          }
│        ]
│      }
│    }
│                                             │
└─────────────────────────────────────────────┘

Steps:
1. Add an HTTP action to your flow
2. Set Method to "POST"
3. Set URI to "https://api.docbutterfly.com/api/ImportHtmlTemplate"
4. Add the headers shown above
5. Paste the Body JSON into the Body field
6. Replace placeholder values with dynamic content as needed
Try in Testbed