Build a Case Management System Integration
This guide is for vendors and system integrators that connect a case management system (CMS) to eCourtDate for more than one agency. The integration sends source data to eCourtDate: clients, contacts, events, cases, and payments. Each agency's configuration in eCourtDate decides which messages go out, when they go out, in which language, and from which phone number or email address.
The integration does not write or schedule messages. One integration build works for every agency that uses the same template configuration.
Overview
| Step | Where | Who |
|---|---|---|
| 1. Build a template agency | Console and Agency app | Integrator, with eCourtDate |
| 2. Create each agency | Console, Tools | Super Admin of the customer profile |
| 3. Set up each agency's senders and settings | Agency app, Admin > Settings | Agency admin |
| 4. Provision API credentials | Console, APIs | Super Admin of the agency |
| 5. Sync clients and contacts | CMS integration | Integrator |
| 6. Sync events, cases, and payments | CMS integration | Integrator |
| 7. Update records when the CMS changes | CMS integration | Integrator |
| 8. Test in staging and go live | Staging agency, then production | Integrator and agency |
How the Integration Works
The integration follows the record lifecycle in the CMS:
- Create a client with the client's phone numbers and email addresses.
- Create the client's events, cases, and payments.
- Update each record when it changes in the CMS.
eCourtDate does the messaging work from those records:
- Flows schedule reminders for each event and payment, for example 3 days and 1 day before a hearing.
- Auto messages send when a record is created or gets a specific status, for example a confirmation when a payment is recorded.
- Statuses with Disable Messages stop reminders, for example when a hearing is canceled or a balance is paid.
- Templates in each flow and auto message hold the wording and the translations. The client's
languageselects the template.
When an event date changes, eCourtDate removes the unsent reminders and schedules new ones from the new date. The integration sends only the new date.
Use one-off messages only for notices that no record represents, for example an emergency court closure.
Step 1: Build a Template Agency
A template agency holds the configuration that every agency copies. The integration code uses the same reference values for every agency, so it does not need settings for each agency.
What to put in the template
| Item | Purpose | Reference the integration sends |
|---|---|---|
| Flows | Reminder schedule and templates for each kind of event or payment. Create one flow for each category that needs different wording or timing. Set the type of each payment flow to payment. | flow_reference on each event and payment |
| Auto messages | Messages sent on a trigger, such as client_created, event_created, event_status, event_appeared, case_created, payment_created, and contact_created | None. The trigger fires from the record action. |
| Statuses | Event, payment, and client status values. Mark the statuses that end messaging (for example canceled, dismissed, paid) with Disable Messages. | status on each record |
| Portals | The web portal linked in messages | portal_reference on each event |
| Locations | Courtrooms and offices, with address and directions | location_reference on each event |
Give each flow, portal, and location a reference value that does not change. Record these values in the integration's mapping, for example:
| CMS value | eCourtDate field | Value |
|---|---|---|
Hearing type ARR | flow_reference | arraignment |
Hearing type TRL | flow_reference | trial |
Courtroom 2A | location_reference | courtroom-2a |
Disposition DISM | status | dismissed |
Create the template
- Create a staging agency for the template. See Step 2.
- In the Agency app, create the flows, auto messages, statuses, portals, and locations. See How to Manage Flows, How to Manage Auto Messages, and How to Disable Messages Based on Status.
- Set a
referenceon each flow, portal, and location. - Add templates in each language that the agencies use. See Multilingual Messaging.
Always send flow_reference on each event and payment. Do not depend on the agency's default flow. The reference keeps the integration the same across agencies.
Step 2: Create Each Agency
Each agency gets a staging agency for testing and a production agency for live messages. Both are created the same way.
Create the agency
- In the Console, click Tools.
- In Create Agency, select the Customer.
- Enter the Agency Name.
- Select the Region. Select Staging for the test agency, or the assigned production region.
- Select the Time Zone. eCourtDate reads event dates and times in this time zone.
- In User Emails, enter the email addresses of the people who manage the agency.
- Click Create Agency.
A new agency starts in Simulate send mode. It has no flows, auto messages, statuses, phone numbers, or email addresses.
Copy the template configuration
- In the Console, click Tools.
- In Copy Settings, select the template agency in From Agency.
- Select the new agency in To Agency.
- In Copy Settings, select
flows,auto_messages,statuses,portals, andlocations. - Select Confirm copy.
- Click Run Tool. eCourtDate sends an email when the copy is complete.
The signed-in user must be a Super Admin in both agencies. The copy works from a staging agency to a production agency.
Copy Settings does not copy agency settings, phone numbers, or email addresses. Step 3 covers them.
After the copy, update the locations with the agency's real addresses. Keep the location_reference values.
Step 3: Set Up Each Agency's Senders and Settings
These items are different for each agency. The agency admin sets them in the Agency app under Admin > Settings.
| Item | Why it is required |
|---|---|
| Agency phone | eCourtDate has no shared sender number. Text and voice reminders do not send until the agency has an active agency phone marked Primary. See How to Manage Agency Phone Numbers. |
| Carrier registration | US carriers block text messages from unregistered numbers. See Carrier Registration. |
| Agency email | eCourtDate has no shared sender address. Email reminders do not send until the agency has an agency email. See Email Domains. |
| Time zone | Event times are read in the agency time zone. A wrong time zone moves every reminder. |
| Languages | Enable each language that has templates. See Multilingual Messaging. |
| Business hours | Flows that delay messages to business hours use these values. |
| Client duplicates | Set the fields that identify one client, for example client_reference. With this setting, a create request for a client that exists returns the existing client. See Clients. |
To read an agency's current settings, send GET /v1/settings. The response includes name, reference, timezone, and send_mode.
Step 4: Provision API Credentials
Create the API client
An API client has a Client ID and a Client Secret. Only a Console user who is a Super Admin in the agency can create one.
- In the Console, click APIs.
- Select the customer profile in the top left.
- Enter a Name that identifies the integrator and the environment, for example
CMS Vendor Staging. - Select the Region. Select Staging for the staging client, or the agency's production region.
- Click Create. The API client opens.
- Select the Default Agency.
- Under Additional Enabled Agencies, select the other agencies that the integration serves.
- In Allowed IPs, enter the public IP addresses of the integration servers, separated by commas.
- Click Save changes.
Scope of one API client
- An API client works in one region. Create one API client for staging and one for each production region.
- An API client can access only agencies in the same customer profile and region. Agencies under different customer profiles need different API clients.
- The API client's Allowed IPs accepts exact IP addresses only. Leave it empty to accept requests from any IP address.
- The API accepts requests only from IP addresses in the United States.
Store the credentials
- Keep the Client ID and Client Secret in a secrets manager, never in source code, tickets, email, or screenshots.
- Store one credential record for each API client, with the API host for its region. See Environments for the hosts.
- Store each agency's
agency_referencewith the credential record that can access it. - To replace a secret, create a new API client, deploy its credentials, and then click REVOKE on the old API client. Revoking stops the old client's tokens immediately.
Get and reuse a token
Send the Client ID and Client Secret to the token endpoint:
curl -X POST "$BASE_URL/oauth/token" \
-H "Content-Type: application/json" \
-d '{
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET",
"grant_type": "client_credentials"
}'
Store the access_token and send it on every request in the Authorization: Bearer header. The token endpoint accepts 5 requests per minute from each IP address, so do not request a token for each API call. Request a new token when the API returns 401. See Authentication.
Select the agency on every request
Send agency_reference on every request, in the query string or in the request body:
curl -X GET "$BASE_URL/v1/settings?agency_reference=example_agency_123" \
-H "Authorization: Bearer $TOKEN"
eCourtDate runs a request against the API client's Default Agency when the request has no agency_reference, or has a reference that the API client cannot access. eCourtDate does not return an error. Before the first sync for an agency, send GET /v1/settings with the agency_reference and confirm that the reference in the response is the same value.
Step 5: Sync Clients and Contacts
Create a client with contacts
Send POST /v1/clients with the CMS person ID in client_reference and the contacts in the same request:
curl -X POST "$BASE_URL/v1/clients?agency_reference=example_agency_123" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"client_reference": "P-100245",
"first_name": "Alex",
"last_name": "Sample",
"language": "es",
"phones": "5551234567",
"emails": "alex.sample@example.com"
}'
phonesandemailsare comma-separated strings, not arrays.languageselects the template language for the client's messages. An unknown code storesen.- A new client fires the
client_createdtrigger. - Store the
uuidfrom the response with the CMS person record.
Prevent duplicate clients
POST /v1/clients does not update a client that exists. A second request with the same client_reference creates a second client, unless the agency's Client duplicates setting includes client_reference. With that setting, the API returns the existing client with status 200 instead of 201.
Before a create, look up the client when the integration has no stored uuid:
curl -X GET "$BASE_URL/v1/clients?client_reference=P-100245&agency_reference=example_agency_123" \
-H "Authorization: Bearer $TOKEN"
Add a contact to a client that exists
Send POST /v1/contacts with client, value, and channel (text, voice, or email). Always send channel. A new contact fires the contact_created trigger. A contact with the same value and channel on the same client returns 409.
Reminders that are already scheduled do not include the new contact. To add it, send POST /v1/clients/{uuid}/sync. See Contacts.
Step 6: Sync Events, Cases, and Payments
Events
Send POST /v1/events for each hearing or appointment:
curl -X POST "$BASE_URL/v1/events?agency_reference=example_agency_123" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"client_reference": "P-100245",
"event_reference": "H-2026-55821",
"case_number": "CR-2026-001234",
"date": "2026-12-14",
"time": "09:00",
"flow_reference": "arraignment",
"location_reference": "courtroom-2a",
"portal_reference": "public",
"status": "scheduled"
}'
dateis required.- An event without a client gets no reminders.
- eCourtDate looks up
flow_reference,location_reference, andportal_referenceby reference or name. When a value does not match, the agency's default is used. - A new event fires
event_created, and alsoevent_statuswhenstatusis set. - An event with a date more than 90 days in the past is saved but not processed.
POST /v1/eventsdoes not checkevent_referencefor duplicates. Look up the event withGET /v1/events?event_reference=...before a create when the integration has no storeduuid.
To send reminders to more than one party for the same hearing, see Attaching Additional Clients.
Cases
Send POST /v1/cases with case_number and client. A new case with a client fires the case_created trigger. Case updates do not fire triggers. See Cases.
Payments
Send POST /v1/payments with the client, the amount, and flow_reference. A new payment fires payment_created when it has a client, an amount greater than zero, and a status that does not disable messages. eCourtDate then schedules the payment flow reminders. See Payments.
Step 7: Update Records When the CMS Changes
Send PATCH with the stored uuid and only the fields that changed. Clients, events, and cases also accept the reference in the path in place of the uuid.
| CMS change | Request | Result in eCourtDate |
|---|---|---|
| Hearing moved | PATCH /v1/events/{uuid} with new date and time | Unsent reminders are removed and scheduled again from the new date. A reminder already sent for the old date is not sent again. |
| Hearing canceled or dismissed | PATCH /v1/events/{uuid} with a status that has Disable Messages | Unsent reminders are removed. No new reminders are scheduled. |
| Status changed | PATCH /v1/events/{uuid} with the new status | The event_status auto message for that status sends one time for each event and contact. |
| Appearance recorded | PATCH /v1/events/{uuid} with appeared | The event_appeared auto message for that value sends one time for each event and contact. |
| Hearing removed | PUT /v1/events/{uuid}/archive | Unsent messages for the event are removed. |
| Balance changed | PATCH /v1/payments/{uuid} with the new amount | Unsent reminders are scheduled again with the new amount. |
| Balance paid | PATCH /v1/payments/{uuid} with a status that has Disable Messages | Unsent reminders are removed. |
| Person details changed | PATCH /v1/clients/{uuid} | Reminders for the client's upcoming events and payments are scheduled again. |
| Phone or email changed | PATCH /v1/contacts/{uuid} | The contact is updated. Send POST /v1/clients/{uuid}/sync to apply it to scheduled reminders. |
| Person asked to stop | PUT /v1/contacts/{uuid}/optout | The contact gets no more messages. Unsent messages to it are removed. |
A client who replies STOP to a text is opted out automatically. The integration does not need to do anything.
Initial load and backfill
For a first load of records that already exist in the CMS, send "skip_sync": true on each event. eCourtDate saves the event without auto messages and without reminders. After the load, send POST /v1/events/{uuid}/process for each upcoming event to schedule its reminders.
skip_sync does not stop auto messages for clients and payments. Turn off the client_created and payment_created auto messages during a backfill, or load the agency while it is in Simulate send mode.
Step 8: Test in Staging and Go Live
- Point the integration at the staging agency and the staging API host.
- Send a test client with a phone number, and an event 3 days in the future.
- In the Agency app, open the client and confirm that the reminders are scheduled. Staging simulates every message, so nothing is delivered.
- Change the event date, and confirm that the reminders move.
- Set the event to a status with Disable Messages, and confirm that the reminders are removed.
- Repeat the test for payments and cases.
- Create the production API client, and switch the integration to the production host and credentials.
- Ask the agency admin or eCourtDate to change the production agency's send mode from Simulate to Live.
To receive delivery results and inbound replies in the CMS, set up webhooks for outbound_texts, outbound_emails, inbound_texts, and inbound_emails.
Reference
Triggers by record action
| Record action | Auto message trigger |
|---|---|
| Create client | client_created, plus client_status and client_group when set |
| Update client | client_updated, plus client_status and client_group when sent |
| Create contact | contact_created |
| Update contact | contact_updated |
| Create event | event_created, plus event_status and event_appeared when set |
| Update event | event_status and event_appeared when the event has a value |
| Create case with a client | case_created |
| Create payment | payment_created |
An auto message for an event, case, or payment sends one time for each record and contact. An auto message for a client or contact sends one time for each contact. Contacts sent in the POST /v1/clients request do not fire contact_created.
Minimum configuration for reminders
An event reminder sends only when all of these are true:
- The event has a client, and the client has a contact that is valid, opted in, and set to notify.
- The event has a flow with at least one flow message.
- The agency has a primary agency phone for text and voice, or an agency email for email.
- The event status, the event type, and the location do not have Disable Messages.
- The agency is active and its send mode is Live.
Real-time and batch sync
| Pattern | When to use it |
|---|---|
| Real-time: send each change when the CMS saves it | Changes reach clients quickly. The integration needs retry logic for failed requests. |
| Batch: send changed records on a schedule | Large volumes. A change reaches eCourtDate only at the next batch, so a reminder can send with old data in the time between batches. |
Both patterns use the same requests. Retry 429, 503, and 504 responses with exponential backoff. See Rate Limits and Best Practices.