A developer building a contract review tool wires up PDF4me's Compare Documents endpoint expecting something like a diff: a list of changed lines, maybe a JSON array of insertions and deletions, something to loop over and render in a custom UI. What comes back instead is a single field called document, holding a base64-encoded file. Decode it, save it as a .docx, and open it in Word, and the picture becomes clear. It is a complete second copy of the document, with every change marked up using Word's own Track Changes feature: additions underlined, deletions struck through, each one ready for a reviewer to Accept or Reject from Word's own Review tab, exactly as if a colleague had marked the document up by hand.
That is the entire point of Compare Documents. It automates the same comparison Word already performs with its own built-in Compare feature, without anyone having to open Word to run it. Two documents go in, .docx or .doc, base64-encoded. One finished, reviewable document comes out.
What the endpoint actually hands back
The REST call is a single POST to office/ApiV2Word/CompareDocuments, a base path worth noting on its own: it lives under office/ApiV2Word/, not the /api/v2/ prefix that most other PDF4me Word endpoints use. Four fields are required: firstDocument (an object carrying a Name), firstDocContent (that document's base64 content), and the matching pair, secondDocument and secondDocContent, for the revised version. The response is JSON: document (the result, base64), fileName, success, and errorMessage.
There is no separate diff object anywhere in that response. The comparison result is not data describing the differences, it is a finished Word document that already contains them, styled the way Word itself styles a comparison: additions in one color, deletions struck through in another.
Here is the whole call in Python. There is no official sample for this endpoint yet in PDF4me's own sample repository (the Word folder there currently only covers Disable Tracking Changes), so this is built directly from the live parameter names on the docs page rather than adapted from an existing sample:
import base64
import requests
api_key = "your-pdf4me-api-key"
base_url = "https://api.pdf4me.com"
endpoint = "/office/ApiV2Word/CompareDocuments"
def read_and_encode(path):
with open(path, "rb") as f:
return base64.b64encode(f.read()).decode("utf-8")
payload = {
"firstDocument": {"Name": "original.docx"},
"firstDocContent": read_and_encode("original.docx"),
"secondDocument": {"Name": "modified.docx"},
"secondDocContent": read_and_encode("modified.docx"),
"comparisonOptions": {
"ignoreFormatting": False,
"ignoreFields": True,
"author": "Legal Review"
}
}
headers = {
"Authorization": f"Basic {api_key}",
"Content-Type": "application/json"
}
response = requests.post(base_url + endpoint, json=payload, headers=headers)
result = response.json()
if result.get("success"):
with open(result["fileName"], "wb") as f:
f.write(base64.b64decode(result["document"]))
print(f"Comparison saved to {result['fileName']}")
else:
print(f"Comparison failed: {result.get('errorMessage')}")
Using the result means decoding that base64 string, saving the bytes as a .docx, and opening it in Word (or a library that understands Word's revision markup) to see what changed and accept or reject each mark individually.
That distinction decides how to build around this endpoint. If the deliverable actually needed is a redlined .docx, one call produces the whole thing: decode it, and email it or drop it into a shared drive. PDF4me's own Make and Power Automate integration guides describe exactly that pattern: a new contract version lands in a Drive or SharePoint folder, gets compared against the archived baseline, and the redline goes straight to a legal team for review without anyone opening Word until the review step itself. A version-control variant of the same idea runs Compare Documents across every consecutive pair in a folder of document revisions, producing one comparison artifact per version jump as a running audit trail.
If what's actually needed is a structured list of what changed, so a custom highlighted-diff view can be built or a decision made programmatically about whether a change was material, this endpoint will not hand that over directly. The differences live inside the returned document as Word's own revision markup. Getting them out as data means parsing that markup, not reading it off the API response.
Tuning signal versus noise: the comparisonOptions object
An optional comparisonOptions object is where this endpoint earns its keep. Eight independent boolean flags, plus an author string, decide what counts as a change before the comparison even runs: ignoreFormatting, ignoreCaseChanges, ignoreComments, ignoreTables, ignoreFields, ignoreFootnotes, ignoreTextboxes, and ignoreHeadersAndFooters.
PDF4me's own Zapier and Make guides both call out the same practical trap: leave ignoreFields off, and a document with an auto-updating date field shows a change on every single comparison run, even when nothing else moved. Turning ignoreFormatting on is the other common move, useful when a reviewer cares only about wording, not whether a paragraph got re-bolded along the way. Leaving every flag at its default (tracking everything) is the right call for a compliance or audit-trail use case, where a noisier comparison is the safer one. author is cosmetic but not pointless: it is the name attached to every tracked change in the output, so an automated "Legal Review" comparison run doesn't get mistaken for edits a human actually typed by hand.
Power Automate's version of this endpoint also documents its failure modes plainly, which is worth knowing before the first integration test: an empty first or second document content field returns a named error ("First document is empty" or "Second document is empty"), and a malformed Word file produces "Error loading document from bytes" rather than a generic failure. Those are concrete, checkable error strings, not vague exceptions, which makes them straightforward to handle explicitly rather than catching everything and guessing.
Same operation, four different contracts
This is where Compare Documents gets genuinely tricky to work with across more than one surface, because the same one operation is exposed four different ways depending on the platform, and none of the four agree on shape.
The REST API uses firstDocument and secondDocument, each an object with a Name. Make and n8n both use "First Document Name" and "First Document Content" as field labels, close to the REST names but not identical, and both type the file content as a Buffer rather than a base64 string directly. Power Automate nests everything under an Operation object and capitalizes every comparison option (Operation/comparisonOptions/IgnoreFormatting, not ignoreFormatting), and its output adds a Success and Error Message pair, capitalized, plus a separate Errors array that none of the other three platforms expose at all.
Zapier breaks the naming pattern hardest: the first document field is not called "First Document" at all, it is simply File, paired with Second Document for the revised one. Its output is the biggest surprise of the four. Rather than handing back the compared document directly, Zapier returns a File Url (and an Alternate File Url) to fetch separately: a download link instead of embedded content, a genuinely different retrieval model from the other three platforms. n8n splits the difference again: its JSON response carries fileName, fileSize, success, and an echo of whatever comparisonOptions were sent. The docs page's own response viewer offers a separate Binary tab alongside JSON, Table, and Schema, which points to the comparison document itself arriving through n8n's binary output rather than sitting inside that JSON body, worth confirming against an actual workflow run before assuming it either way.
None of these four are wrong. They are genuinely different response shapes for what is, underneath, the same PDF4me operation. Code written to read the REST response cannot be pointed at the Zapier result without changes, since a URL arrives where a file was expected. A Power Automate error handler checking a lowercase success field silently misses every failure, because Power Automate's field is Success, capitalized. Anyone maintaining the same comparison workflow across more than one of these four platforms is better off writing this down once than rediscovering it after a failed run.
What this is not for
Compare Documents is not the right endpoint if a document already has tracked changes inside it and the goal is to read those changes out or toggle tracking on or off. That job belongs to three separate, related endpoints: Enable Tracking Changes in Word, Get Tracking Changes in Word, and Disable Tracking Changes in Word. Compare Documents starts from two separate files with no shared revision history and builds the tracked-changes view from nothing; that trio instead works with revisions a single document already carries. And if all that's needed from a Word file is its plain text, with no comparison and no revision history involved at all, that is Extract Text from Word, a simpler and unrelated operation.
None of this is a reason to avoid the endpoint. For the job it is built for, comparing contract drafts, reviewing a policy revision, checking a filed legal brief against what was actually submitted, it removes an entire manual step: nobody has to open two files side by side in Word and click Compare themselves. The output is the same kind of file a reviewer already knows how to work with, produced on a schedule or a trigger instead of by hand. The part worth knowing before building on it is that "compare" here means "produce the Word document a human reviewer would produce," not "produce a diff object," and that the four ways to call it are four genuinely different contracts sharing one feature name.
Website: pdf4me.com
Documentation: docs.pdf4me.com
Developer portal: dev.pdf4me.com
Top comments (0)