June 3, 2026 · 11 min read

There Is No Clio Document-Created Webhook. Here's How to Actually Trigger Automation When Docs Generate.

If you've gone looking for a webhook that fires when a document generates in Clio, you've already found the bad news: it doesn't exist. We hit this wall building our open-source Clio MCP connector, and we've watched plenty of firms hit it too. The fix isn't a workaround so much as a different mental model. Trigger on the cause, not the document.

Here's a workflow that sounds trivial and isn't. A matter moves to a litigation stage. Clio's automations generate the documents that stage requires. You want something to happen the instant those documents appear: a draft gets filled, a notification fires, a record gets logged. The natural instinct is to subscribe to a "document created" event and react to it.

That event doesn't exist in the Clio Manage API. Not in 2026, not in any tier. We confirmed it while building our Clio MCP connector, and it's worth writing down clearly because the official docs bury it and most integration guides skip it entirely.

This post covers what Clio webhooks actually fire on, the two reliable ways to detect a new document, why Clio Draft can't be triggered from the API at all, and the upload and custom-field traps that bite you right after you solve the trigger problem. Everything here is API behavior we've verified, not theory.

What Clio webhooks actually fire on

Clio supports webhooks for a fixed set of resource events. As of mid-2026, the list is:

  • activity
  • bill
  • calendar_entry
  • communication
  • contact
  • matter
  • task

No document. That's the whole story. There is no event for document created, document generated, or document uploaded. If your automation depends on reacting to a new file in a matter, none of these events will hand it to you directly.

Two more things matter about Clio webhooks before you build on them. They expire. The default lifespan is three days, with a maximum of 31, so your integration has to renew its subscriptions on a schedule or it goes quietly dead. And they're per-resource, so you subscribe to the resource type and filter on the payload, rather than asking for a narrow "documents in matter 12345" feed.

The reframe that unblocks this: documents in Clio don't appear from nowhere. They appear because a matter changed. A stage advanced, a status flipped, an automation ran. That change is something you can subscribe to. So instead of waiting for the document, you watch for the thing that produces it.

Option 1: subscribe to the matter updated webhook

Clio Draft document automation generates documents when a matter hits a defined litigation stage. The stage change is the cause; the documents are the effect. And the stage change fires a matter updated webhook.

So the pattern is: subscribe to matter events, watch for the stage transition that you know triggers generation, then read that matter's documents to pick up whatever was just created. You're not catching the document event because there isn't one. You're catching the event one step upstream and following the causal chain.

This is the cleaner option when you can use it, because it's event-driven. No constant polling, no wasted requests. The tradeoff is that you need to know which stage transitions produce documents, and you need a small bit of logic to read the matter's documents after the webhook lands and identify the new one (by created timestamp or by diffing against what you'd seen before).

Option 2: poll the documents endpoint

If the document doesn't come from a clean matter-stage trigger, or you want a dead-simple mechanism that doesn't depend on webhook renewal, poll. Query a matter's documents on an interval and act on anything new since the last check.

Polling carries no shame. For a lot of legal workflows it's the right call, because the latency you care about is minutes, not milliseconds, and polling removes a whole class of webhook-expiry and delivery-retry failure modes. The discipline is in the rate limits.

Clio's rate limiting is conservative. Plan around roughly 3 requests per second per app (the docs also reference a legacy 50-requests-per-minute figure). Honor the X-RateLimit-* response headers, back off cleanly on a 429, and paginate at 200 records per page. If you poll too aggressively across many matters, you'll burn your budget and starve the rest of your integration. Throttle deliberately and stagger the polls.

Detecting a new Clio document: webhook vs polling

Factor Matter updated webhook Polling
Latency Near real-time As fast as your interval
Needs a public endpoint Yes, to receive callbacks No, runs anywhere
Maintenance Renew before 3-day (max 31) expiry Manage the rate budget (~3 req/s)
Best for Stage-driven document generation Local tools, simple setups, no inbound port

There's no universally correct answer here, which is the point. If your automation runs locally on a lawyer's machine and you don't want to stand up a public callback endpoint, polling is genuinely the better architecture. If you're running a hosted multi-tenant service and want minimal lag, the matter webhook earns its keep. Pick based on where the code runs and how much latency you can tolerate, not on which one sounds more modern.

Why you can't just call the Clio API to generate the document

A reasonable next thought: forget detecting the document, just have the API generate and fill it. That doesn't work either, and it's worth being precise about why.

Clio Draft document automation is UI-only. There is no public API to trigger a template merge or generate a document from a Clio Draft template programmatically. You can read a matter's custom field values, you can write them back, and you can upload a finished file. But the merge-the-template step lives inside Clio's interface and isn't exposed.

So if you need programmatic document assembly, the realistic shape is: read the data you need from Clio via the API, do the merge in your own code (or hand the field data plus a template to an LLM and have it draft the document), then upload the finished file back into the matter. You own the assembly; Clio holds the result. Tools like n8n can orchestrate the read-and-upload halves, but they can't conjure a Clio Draft merge endpoint that Clio doesn't publish.

This same UI-only limitation shows up in the related pain a lot of firms describe: Clio auto-generates the required documents at a litigation stage, but they come out blank. Only the most basic fields (client name, address) carry through. The rich custom-field data the firm maintains doesn't flow into the forms. The API can't fix that merge inside Clio Draft, but it can read every field value and let your own code populate a document outside it.

The upload trap: it's a two-step presigned-S3 flow

Once you've assembled a document, uploading it to Clio is not a single multipart POST. It's three calls, and skipping the last one is the most common upload bug we see:

  1. POST to the documents endpoint to create the document record. Clio responds with a presigned S3 put_url.
  2. PUT the raw file bytes directly to that put_url. The bytes go to S3, not back through Clio's API.
  3. PATCH the document to set fully_uploaded: true.

Miss step three and you get an orphaned document record with no retrievable content. The file is technically in S3, but Clio doesn't consider the upload complete, so the document is effectively invisible in the matter. We built this flow into the connector's upload_document tool precisely because getting it wrong by hand is so easy.

The custom-field trap: value-instance id, not field id

If your automation also reads or writes custom fields (and most document workflows touch them), there's one trap that costs more debugging time than anything else in the Clio API.

You read custom fields with GET matter?fields=custom_field_values{...} and you write them by PATCHing the matter with a nested custom_field_values array. The trap is in the id. The id inside custom_field_values is the value-instance id, not the field-definition id (the custom_field:{id} reference).

The field-definition id identifies the field across all matters. The value-instance id identifies one specific value on one specific matter. Pass the field-definition id where the value-instance id belongs and the write fails silently or lands on the wrong target. There's no row limit that bites here, fields numbering into the hundreds are fine, but each field's type has rules. Free-text normalizes cleanly. Picklist values must match a predefined option (and options cap around 55 characters). Currency rejects decimals you didn't expect. Date wants valid dates. Inventory your fields by type before you promise blanket normalization, because the API will reject a clean-looking string that doesn't fit the field's type.

A note on the human-review gate

If the document you're triggering on gets drafted or filled by an AI model, the trigger is the easy part. The harder requirement is the review step you build after it. The Law Society of Ontario's 2024 practice guidance on generative AI, conceptually aligned with ABA Formal Opinion 512, points to a duty of competence and a mandatory human verification of AI outputs. A lawyer reviews and finalizes; the automation never publishes unreviewed work into the record.

This isn't a Clio API detail, but it's the reason we bake a human-review handoff into every legal automation we build. The automatic trigger should produce a draft for a lawyer to approve, not a finished filing. Build the gate in from the start; retrofitting it after the fact is where compliance problems live.

Does MyCase or PracticePanther do it differently?

If you're choosing a practice management platform partly on automation reach, the document-webhook gap isn't unique to Clio. Practice management APIs in this category tend to expose webhooks for the core resources (matters, contacts, calendar, billing) and treat document generation as an internal feature rather than an event you can subscribe to. We've built connectors against both Clio and MyCase, and the same "trigger on the cause, not the document" pattern applies. PracticePanther sits in the same general shape. The takeaway: don't pick a platform expecting a document-created webhook, because you'll likely be polling or watching matter-level events whichever you choose.

Frequently asked questions

Does Clio have a document-created webhook?

No. As of 2026, the Clio Manage API does not offer a webhook for document creation or generation. Clio webhooks cover activity, bill, calendar_entry, communication, contact, matter, and task events only. There is no document event. To detect a new document, you either poll the documents endpoint on a schedule or subscribe to the matter updated webhook and treat the stage change that triggers generation as your signal.

How do I trigger automation when a document generates in Clio?

Because there is no document webhook, trigger on the cause rather than the document itself. Clio Draft document automation generates documents when a matter hits a litigation stage, and that stage change fires a matter updated webhook. Subscribe to that webhook, then read the matter's documents to find the new draft. If you cannot use webhooks, poll the documents endpoint on a schedule. Throttle to roughly 3 requests per second and honor the X-RateLimit headers.

Can the Clio API generate or fill a Clio Draft document automation template?

No. Clio Draft document automation is UI-only. There is no public API endpoint to trigger generation or merge field data into a template programmatically. You can read and write a matter's custom field values via the API, and you can upload a finished document back into a matter, but the template merge step itself happens inside Clio's interface. If you need programmatic document assembly, build the merge in your own code and upload the result with the two-step document upload flow.

How do you upload a document to Clio via the API?

Clio uses a two-step presigned-S3 upload. First POST to the documents endpoint to create the document record and receive a presigned put_url. Second, PUT the file bytes directly to that S3 URL. Third, PATCH the document to mark fully_uploaded as true. Skipping the final PATCH leaves an orphaned record with no content, which is the most common upload bug we see.

Why does writing a Clio custom field value fail with the field id?

The id you pass inside the custom_field_values array is the value-instance id, not the field-definition id. The field-definition id (the custom_field reference) identifies the field; the value-instance id identifies the specific value on that specific matter. Passing the field-definition id where the value-instance id belongs is the single most common reason custom field writes fail silently or hit the wrong field.

Building automation on top of Clio?

We built the open-source Clio and MyCase MCP connectors, so we've already hit the webhook gaps, the upload flow, and the custom-field traps. If you want a document-triggered workflow that stays compliant and actually fires reliably, we can help.

See Our Legal AI Integration Service →

API behavior described here was verified against the Clio Manage API while building our open-source Clio MCP connector (live on npm as @oktopeak/clio-mcp). Clio's API evolves. If a detail here is out of date, email office@oktopeak.com and we'll correct it.

Legal Tech

Related Articles

View all Legal Tech articles ➔

Book a Call