Skip to main content

Payments

A payment record tracks an amount an individual owes to an agency: a fine, fee, restitution, bond, or any other balance due. Creating a payment record does not charge anyone and does not move money. eCourtDate uses the record to schedule automated reminder messages through the payment's flow, and each reminder can include a link the recipient uses to view and pay the balance through the agency's portal.

All endpoints use the base URL for your assigned region (see Environments & Regions) and require a Bearer token (see Authentication):

Authorization: Bearer {access_token}
Content-Type: application/json

Endpoints

MethodPathDescription
GET/v1/paymentsList payments
GET/v1/payments/totalCount payments matching filters
GET/v1/payments/uniquesList distinct values for a field
GET/v1/payments/{uuid}Get a single payment
POST/v1/paymentsCreate a payment
PATCH/v1/payments/{uuid}Update a payment
DELETE/v1/payments/{uuid}Delete a payment (soft delete)
PUT/v1/payments/{uuid}/archiveArchive a payment
PUT/v1/payments/{uuid}/restoreRestore an archived or deleted payment
POST/v1/payments/{uuid}/processReprocess a payment (reschedule reminders)

The Payment Object

FieldTypeDescription
uuidstringUnique identifier, generated when the payment is created.
clientstringUUID of the client who owes the payment. Reminders are sent to this client's contacts.
payment_referencestringYour identifier for the payment, such as an invoice, receipt, or ticket number. Auto-generated as a random 12-character value when omitted on create.
amountnumberAmount due. Must be greater than zero.
statusstringCurrent status. Statuses are agency-defined text values, such as draft, outstanding, or paid.
typestringPayment type, such as fine or fee. Types are agency-defined text values.
issued_atstringIssue date in YYYY-MM-DD format.
due_atstringDue date in YYYY-MM-DD format.
descriptionstringShort description of what the payment is for.
notesstringAdditional notes about the payment. Available to messages via the [PaymentNotes] merge tag.
case_numberstringCase number tied to the payment.
citationstringCitation identifier tied to the payment.
flowstringUUID of the flow that schedules this payment's reminder messages.
portalstringUUID of the portal that hosts the payment's page.
locationstringUUID of the location tied to the payment.
location_notesstringNotes about the payment's location.
contactstringContact tied to the payment.
uploadstringUUID of the file import associated with the payment, when the payment is linked to a file import.
urlstringUnique slug for the payment's link. The [PaymentLink] merge tag resolves to this link in messages. Generated automatically.
created_bystringEmail or UUID of the user or API client that created the payment.
created_atstringCreation timestamp, UTC, YYYY-MM-DD HH:MM:SS.
updated_atstringLast update timestamp, UTC.
archived_atstringSet when the payment is archived, otherwise null.
deleted_atstringSet when the payment is deleted, otherwise null.

Responses also include computed amount fields:

FieldTypeDescription
raw_amountstringThe stored amount with currency symbols and commas removed.
amountnumberThe amount as a number.
formatted_amountstringThe amount prefixed with the currency symbol, for example $250.75.

Retrieving a single payment (GET /v1/payments/{uuid}) also returns the names of related records: flow_name, location_name, and portal_name. These are null when the related record is not set, archived, or deleted. List responses omit these name fields.

Create a Payment

POST /v1/payments

Request:

curl -X POST "$BASE_URL/v1/payments" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"client_reference": "CLIENT-12345",
"payment_reference": "INV-2024-0042",
"amount": 250.75,
"type": "fine",
"status": "outstanding",
"issued_at": "2024-03-01",
"due_at": "2024-03-31",
"case_number": "CASE-2024-001",
"description": "Traffic fine"
}'

Response (201):

{
"uuid": "{payment_uuid}",
"client": "{client_uuid}",
"payment_reference": "INV-2024-0042",
"amount": 250.75,
"raw_amount": "250.75",
"formatted_amount": "$250.75",
"type": "fine",
"status": "outstanding",
"issued_at": "2024-03-01",
"due_at": "2024-03-31",
"case_number": "CASE-2024-001",
"description": "Traffic fine",
"flow": "{flow_uuid}",
"portal": "{portal_uuid}",
"location": "{location_uuid}",
"url": "aB3dE5fG7hJ9",
"created_by": "integration@agency.gov",
"created_at": "2024-03-01 14:22:05"
}

Request Fields and Defaults

Only amount is required. Every other field is optional and falls back to a default:

FieldDefault when omitted
amountRequired. Currency symbols ($, ¢) and commas are stripped, then the value must be numeric and greater than zero, otherwise the API returns 400 with Invalid Payment amount. 250.75, "250.75", "$250.75", and "$1,250.00" are all accepted and stored as 1250.00.
client / client_referenceNo client is attached. Payments without a client do not generate reminder messages. See Attaching a Client.
payment_referenceA random 12-character value is generated.
issued_atToday's date in the agency's timezone.
due_atissued_at plus the agency's Payment Due Date setting (30 days when the setting is not configured).
statusThe agency's default payment status setting, or draft when no default is configured.
typeThe agency's default payment type setting, or null.
flowThe agency's default payment flow. See Attaching a Flow.
portalThe agency's default portal.
locationThe agency's default location.
urlA unique random slug is generated. This becomes the payment's link.

Attaching a Client

Identify the client with either field:

  • client: the client's UUID.
  • client_reference: your identifier for the client, as stored on the client record.

The API matches only active clients (not archived, not deleted). If no match is found, the payment is created without a client, the response omits the client field, and no reminder messages are scheduled. Verify the client field in the response when reminders matter.

Attaching a Flow

A flow defines the reminder message schedule for the payment (for example: a message when the payment is issued, 7 days before the due date, and on the due date). Identify the flow with flow (UUID), flow_reference, or the flow's exact name. If no value is provided or no match is found, the agency's default payment flow is used; when no payment flow is flagged as the default, the first payment-type flow found is used. If the agency has no payment-type flow at all, no reminders are scheduled.

What Happens After Create

  1. The payment is saved and returned with a 201 status.
  2. If a client is attached and the payment's status and type are not flagged with Disable Messages, a payment_created auto message trigger fires. Agencies can configure an auto message for this trigger to confirm the new balance to the client.
  3. The payment is queued for processing, which schedules reminder messages from the flow. See How Payment Reminders Work.

Pass "skip_sync": true in the request body to skip step 3, the flow reminder processing. The record is still saved, and the payment_created auto message in step 2 still fires if configured, so skip_sync suppresses only the scheduled flow reminders, not a confirmation auto message.

List Payments

GET /v1/payments
curl -X GET "$BASE_URL/v1/payments?status=outstanding&due_from=2024-03-01&due_to=2024-03-31&limit=50" \
-H "Authorization: Bearer $TOKEN"

Response (200): a JSON array of payment objects.

Query Parameters

Filtering:

ParameterDescription
searchPartial match on payment_reference.
payment_referenceExact match on payment_reference. reference is an accepted alias.
clientFilter by client UUID.
statusFilter by exact status.
typeFilter by exact type.
case_numberFilter by exact case number.
citationFilter by exact citation.
descriptionFilter by exact description.
flowFilter by flow UUID.
portalFilter by portal UUID.
locationFilter by location UUID.
contactFilter by contact.
uploadFilter by the file import (upload) UUID that created the payments.
urlFilter by the payment's link slug.
due_fromPayments with due_at on or after this date (YYYY-MM-DD).
due_toPayments with due_at on or before this date.
issued_fromPayments with issued_at on or after this date.
issued_toPayments with issued_at on or before this date.
archivedSet to 1 to return only archived payments. By default, archived payments are excluded.
trashedSet to 1 to return only deleted payments. By default, deleted payments are excluded. deleted is an accepted alias.

Pagination and shaping:

ParameterDefaultDescription
limit10Records per page. Maximum 100.
skip0Records to skip.
sortcreated_atField to sort by. Any payment field is accepted.
sortDirectiondescasc or desc.
fieldsall fieldsComma-separated list of fields to return, for example fields=uuid,amount,status,due_at.

Combine date filters for common reports. Payments coming due this month: ?due_from=2024-03-01&due_to=2024-03-31. Payments issued last week that are still in a given status: ?issued_from=2024-02-19&issued_to=2024-02-25&status=outstanding.

Count Payments

GET /v1/payments/total

Returns the number of payments matching the same filters as List Payments, as a bare number. Useful for pagination math and dashboards without transferring records.

curl -X GET "$BASE_URL/v1/payments/total?status=outstanding" \
-H "Authorization: Bearer $TOKEN"

Response (200):

42

List Distinct Values

GET /v1/payments/uniques

Returns the distinct values in use for one field, as a JSON array of strings. Supported fields: type (default) and description. Any other field returns 400 with Invalid unique attribute. Use this to build filter dropdowns from values agencies actually use. This endpoint honors the limit parameter, so it returns at most 10 values by default; pass limit=100 for a fuller list.

curl -X GET "$BASE_URL/v1/payments/uniques?field=type" \
-H "Authorization: Bearer $TOKEN"

Response (200):

["fine", "fee", "restitution"]

Get a Payment

GET /v1/payments/{uuid}

Returns the payment object, including the computed amount fields and the related record names (flow_name, location_name, portal_name). Returns 404 with a message of Payment {uuid} not found when no payment matches.

curl -X GET "$BASE_URL/v1/payments/{payment_uuid}" \
-H "Authorization: Bearer $TOKEN"

Response (200):

{
"uuid": "{payment_uuid}",
"client": "{client_uuid}",
"payment_reference": "INV-2024-0042",
"amount": 250.75,
"raw_amount": "250.75",
"formatted_amount": "$250.75",
"type": "fine",
"status": "outstanding",
"issued_at": "2024-03-01",
"due_at": "2024-03-31",
"case_number": "CASE-2024-001",
"citation": null,
"description": "Traffic fine",
"notes": null,
"flow": "{flow_uuid}",
"flow_name": "Payment Reminders",
"portal": "{portal_uuid}",
"portal_name": "Agency Portal",
"location": "{location_uuid}",
"location_name": "Main Courthouse",
"location_notes": null,
"contact": null,
"upload": null,
"url": "aB3dE5fG7hJ9",
"created_by": "integration@agency.gov",
"created_at": "2024-03-01 14:22:05",
"updated_at": "2024-03-01 14:22:05",
"archived_at": null,
"deleted_at": null
}

Single-payment responses are cached. After an update through the API the cache is refreshed automatically; changes made outside the API can take a short time to appear.

Update a Payment

PATCH /v1/payments/{uuid}

Send only the fields you want to change. Fields not included are left as they are. updated_at is set automatically.

curl -X PATCH "$BASE_URL/v1/payments/{payment_uuid}" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"status": "paid"
}'

Response (200): the updated fields.

After a successful update the payment is reprocessed: unsent scheduled reminders are removed and rescheduled from the flow using the payment's current data. Messages already sent are not affected. If the new status or type is one the agency has flagged to disable messages (for example a paid status), no new reminders are scheduled. See How Payment Reminders Work.

Unlike create, PATCH writes the fields you send without applying defaults, so send complete values (for example, a full YYYY-MM-DD date for due_at).

Updating the Amount

To change a payment's amount, send a PATCH with the new amount, and optionally a new status in the same request:

curl -X PATCH "$BASE_URL/v1/payments/{payment_uuid}" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"amount": 175.00,
"status": "partial"
}'

The amount is normalized the same way on update as on create: currency symbols ($, ¢) and commas are stripped, and the value must be numeric and greater than zero, so 175.00, "175.00", and "$1,175.00" are all accepted. After the update, reminders are rescheduled from the payment's current data, so future messages using [PaymentAmount] reflect the new value; already-sent messages keep the amount they were sent with. To stop reminders once a balance is settled, update the status to one the agency flags to disable messages, or archive the payment, rather than setting the amount to zero.

Delete a Payment

DELETE /v1/payments/{uuid}

Soft-deletes the payment by setting deleted_at. Any scheduled, unsent reminder messages for the payment are cancelled. The record remains retrievable with the trashed=1 list filter and can be brought back with Restore.

Response (204): no body.

Archive a Payment

PUT /v1/payments/{uuid}/archive

Sets archived_at, removes the payment from default list results, and cancels any scheduled, unsent reminder messages. Archiving suits payments that are resolved or no longer active but should stay out of the trash. Archived payments are retrievable with the archived=1 list filter.

Response (200):

{"message": "Payment {payment_uuid} archived"}

Restore a Payment

PUT /v1/payments/{uuid}/restore

Clears both archived_at and deleted_at, marks the payment as unprocessed, and queues it for processing, which reschedules reminder messages from the flow.

Response (200):

{"message": "Payment {payment_uuid} restored"}

Reprocess a Payment

POST /v1/payments/{uuid}/process

Queues the payment for processing: scheduled unsent reminders are removed and rebuilt from the payment's flow and current data. Use this after changing a client's contacts, editing the flow, or fixing payment data, to bring the reminder schedule back in line. /v1/payments/{uuid}/sync is an accepted alias for the same operation.

Response (202):

{"message": "Syncing Payment"}

Returns 400 when the {uuid} path value is not a valid UUID.

How Payment Reminders Work

When a payment is created, updated, restored, or reprocessed, eCourtDate rebuilds its reminder schedule:

  1. Scheduled, unsent flow reminder messages attached to the payment are removed. Messages already sent are kept, and unsent auto messages (such as a payment_created confirmation) are also kept.
  2. The payment's flow defines which messages to send and when, relative to dates such as the issue and due date.
  3. One message is scheduled per flow step for each of the client's notifiable contacts (phone and email).

No reminders are scheduled when any of the following is true:

  • The payment has no client attached, or the client has no notifiable contacts.
  • The payment has no flow, or its flow has no messages.
  • The payment amount is zero or missing.
  • The payment is archived or deleted.
  • The payment's status or type matches an agency status with Disable Messages enabled. Agencies typically flag statuses like paid this way so reminders stop once a balance is settled.
  • The client's status, type, or group matches an agency client status with Disable Messages enabled.

If reminders are not going out, check these conditions in order: confirm the response from GET /v1/payments/{uuid} shows a client and a flow, then confirm the client has opted-in contacts (GET /v1/contacts?client={client_uuid}), then review the payment's status against the agency's status settings.

Merge Tags in Payment Messages

Reminder messages and one-off messages attached to a payment can include these merge tags:

TagInserts
[PaymentAmount]The payment amount.
[PaymentDueDate]The due date.
[PaymentIssueDate]The issue date.
[PaymentReference]The payment reference.
[PaymentLink]The payment's unique link.
[PaymentStatus]The status.
[PaymentType]The type.
[PaymentDescription]The description.
[PaymentNotes]The notes.
[PaymentCitation]The citation.
[TotalPayments]The client's total payment balance. Needs only a client, not an attached payment.

See Merge Tags for resolution rules and the full tag catalog.

Sending a One-Off Payment Message

To send a single message about a payment outside the flow schedule, attach the payment when sending:

curl -X POST "$BASE_URL/v1/messages/oneoffs" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"to": "+15551234567",
"subject": "Balance Due",
"content": "You owe [PaymentAmount] by [PaymentDueDate]. Pay online: [PaymentLink]",
"payment": "{payment_uuid}"
}'

To list every message tied to a payment: GET /v1/messages?payment={payment_uuid}.

Webhooks

Payment webhook events are delivered when payment transactions are processed. Subscribe to keep an external system in sync without polling. See Webhook Event Types and Webhook Configuration.

FAQs

Does creating a payment charge the client or process a transaction?

No. A payment record tracks an amount owed. The recipient pays through the agency's portal using the payment link, and payment webhook events report transaction activity. The API record is the source for reminders and reporting, not a charge instruction.

How do I update a payment's amount?

Send a PATCH /v1/payments/{uuid} with the new amount, and optionally a new status in the same request, for example {"amount": 175.00, "status": "partial"}. The amount is normalized the same way as on create, so currency symbols and commas are accepted. The update reprocesses the payment, so future reminder messages reflect the new amount; messages already sent are unchanged. This is the recommended way to record a revised balance or a partial payment.

What formats does amount accept?

Numbers and numeric strings, with or without currency symbols ($, ¢) and commas: 250.75, "250.75", "$250.75", and "$1,250.00" are all valid. On both create and update, the symbols and commas are stripped and the remaining value must be numeric and greater than zero, or the API returns 400 with Invalid Payment amount.

Which payment statuses are valid?

Statuses are agency-defined text values, not a fixed list. A new payment defaults to the agency's default payment status, or draft when none is configured. To see the statuses an agency uses in practice, list existing payments or check the agency's status settings. Statuses flagged with Disable Messages stop reminder scheduling for payments in that status.

Can I use my own invoice or receipt numbers?

Yes. Set payment_reference when creating the payment and filter by it later with GET /v1/payments?payment_reference=INV-2024-0042. When omitted, the API generates a random 12-character reference.

How do I mark a payment as paid and stop its reminders?

PATCH /v1/payments/{uuid} with the agency's paid status, for example {"status": "paid"}. Updating reprocesses the payment: unsent reminders are removed, and no new ones are scheduled when the status is flagged with Disable Messages. Archiving or deleting the payment also cancels unsent reminders.

Why are no reminder messages going out for a payment?

The most common causes: the payment has no client attached (check the client field on the payment), the client has no opted-in contacts, the payment has no flow with messages, the amount is zero, or the payment's status or type is flagged to disable messages. The full list of conditions is in How Payment Reminders Work.

What is the difference between deleting and archiving a payment?

Both cancel unsent reminders and remove the payment from default list results. Archiving (PUT /v1/payments/{uuid}/archive) is for payments that are resolved or inactive; they remain available with the archived=1 filter. Deleting (DELETE /v1/payments/{uuid}) is a soft delete for records that should not have been created; they remain available with the trashed=1 filter. Either state can be undone with PUT /v1/payments/{uuid}/restore, which also reschedules reminders.

Does updating a payment re-send messages that were already sent?

No. Reprocessing only removes and reschedules messages that have not been sent yet. Delivered messages are never recalled or duplicated by an update.

Can a client have more than one open payment?

Yes. Each payment is an independent record with its own reminders, link, and due date. The [TotalPayments] merge tag inserts the client's combined balance into a message, and GET /v1/payments?client={client_uuid} lists all of a client's payments.

What timezone are payment dates in?

issued_at and due_at are calendar dates (YYYY-MM-DD) interpreted in the agency's timezone; the default issued_at is today's date in that timezone. Timestamps such as created_at and updated_at are UTC in YYYY-MM-DD HH:MM:SS format.

How do I import many payments at once?

The API creates one payment per POST /v1/payments request. For bulk loads, batch your requests within rate limits, or import payments from files over SFTP. When a payment is linked to a file import, its upload field holds the import's UUID, so you can filter by a batch with GET /v1/payments?upload={upload_uuid}.