Legal AI is complicated.
Connecting it shouldn't be.

InfoTrack's Model Context Protocol connects AI agents directly to court filing and service of process — no manual data entry, no portal-hopping, no chasing updates.

The busywork disappears.

InfoTrack Intelligence powers your AI agent. It reads documents, fills forms, and submits filings — automatically. For eFiling and service of process.

✓

Connect Once

Add InfoTrack MCP to your AI client. Simple OAuth 2.0 setup takes minutes.

✓

AI Does The Work

Your agent calls our tools. We extract data, calculate fees, and handle submissions.

✓

You Stay In Control

Review summaries, confirm submissions, track progress — all through your AI assistant.

Simple requirements

🔗

Server URL

Start in Test: https://testsearch.infotrack.com/services/mcp-us-server/mcp

🔑

Client Credentials

We issue your ClientId and ClientSecret once you send us your redirect URIs. There is no self-service portal.

🔐

OAuth 2.0

Authorization code with PKCE. Each of your users signs in with their own InfoTrack account.

Connect to InfoTrack MCP

Before you start

⚠️
Your MCP client must support elicitation

The filing tools collect what they need through MCP elicitation, and they are hidden from clients that do not advertise support for it during initialize. If your client cannot handle elicitation requests, Start_filing will not appear in tools/list at all — it will look as though we have not granted you access. There is no non-elicitation filing path today.

Filing happens inside Start_filing. There is no separate submit tool: the review and confirmation steps are elicitations raised during that call, and an elicitation you never answer leaves a saved draft you can resume later.

You will also need accounts for your users and, before an end-to-end test, your document sources allowlisted.

Choose an environment

Start in Test. It has its own accounts and orders, and connects to the courts' test systems rather than their live ones. Move to Production once your integration works end to end.

EnvironmentMCP endpointAuthorization server
Test — start herehttps://testsearch.infotrack.com/services/mcp-us-server/mcphttps://testauth.infotrack.com
Stagehttps://stagesearch.infotrack.com/services/mcp-us-server/mcphttps://stageauth.infotrack.com
Productionhttps://search.infotrack.com/services/mcp-us-server/mcphttps://auth.infotrack.com
⚠️
Accounts and credentials are per environment

Test credentials do not work against Production and vice versa. Point your MCP endpoint and your authorization server at the same environment — mixing a Test client with the Production authorization server is the most common setup failure we see. You will normally get one ClientId with a different ClientSecret per environment.

Getting your client credentials

There is no self-service portal. We create your OAuth client by hand, because our authorization server does not support Dynamic Client Registration.

1

Send us your redirect URIs

Every URI your client will receive the authorization code on, for each environment. Include local development URIs — plain-HTTP localhost is supported, so http://localhost:3000/callback is fine.

2

We provision your OAuth client

We register the client and its redirect URIs, and enable the authorization code grant, PKCE and offline_access on it.

3

You receive the credentials

Your ClientId and ClientSecret arrive on a 1Password share link that expires — store the secret before it does. The ClientId is a literal string containing spaces; send it exactly as issued.

How the OAuth flow works

Authorization code flow with PKCE. Each of your end users signs in with their own InfoTrack account and authorizes your client; you exchange the resulting code for an access token and a refresh token.

SettingValue
Grant typeauthorization_code (plus refresh_token)
PKCERequired — S256
Authorization endpoint<authorization server>/connect/authorize
Token endpoint<authorization server>/connect/token
Refresh endpoint<authorization server>/connect/token
Client authenticationclient_secret_basic or client_secret_post
Scopesopenid profile infsec:basic infsec:identity api offline_access
🔑
Request offline_access explicitly

offline_access is what issues your refresh token. Without it the connection dies as soon as the access token expires and your user is sent back through the browser. It is not currently listed in our protected-resource metadata, so a client that only requests advertised scopes will silently omit it — request it anyway. Refresh tokens are valid for 30 days, after which the user signs in again. Tell us if your client cannot request a scope we do not advertise.

🔐
This is not client credentials

Our tools act as a signed-in user, so there is no machine-to-machine mode. If you have built against a token endpoint with no redirect URI and no browser step, that is the wrong flow — you will get unauthorized_client at the authorization endpoint.

If you are connecting Courtny users, add auth_scheme=courtny-auth0 to the authorization request so they see the Courtny-branded sign-in page rather than the InfoTrack one: https://testauth.infotrack.com/connect/authorize?auth_scheme=courtny-auth0&…. This value is confirmed for Test only — ask us before hard-coding it for Production.

Configure Your MCP Client

Swap the URL for the environment you want. --client-secret with no value triggers a masked prompt — paste the secret there rather than putting it on the command line.

terminal
claude mcp add-json --scope user infotrack-test \
              '{"type":"http","url":"https://testsearch.infotrack.com/services/mcp-us-server/mcp","oauth":{"clientId":"<CLIENT_ID>","callbackPort":42958}}' \
              --client-secret

The callback port must match a redirect URI we registered for you. Start a new session and run /mcp to authenticate — a browser opens at the authorization server, and after you sign in the entry shows as connected.

Most partners build their own client. Send the user to the authorization endpoint:

authorize request
GET /connect/authorize
              ?client_id=InfoTrack.MCP.US.Server%20-%20Your%20Company
              &response_type=code
              &redirect_uri=https://app.example.com/api/auth/infotrack/callback
              &scope=openid%20profile%20infsec:basic%20infsec:identity%20api%20offline_access
              &code_challenge=<BASE64URL-SHA256-OF-VERIFIER>
              &code_challenge_method=S256
              &state=<CSRF-TOKEN>
            Host: testauth.infotrack.com

Then exchange the code, authenticating your client with the secret:

token request
POST /connect/token
            Host: testauth.infotrack.com
            Authorization: Basic <base64(client_id:client_secret)>
            Content-Type: application/x-www-form-urlencoded

            grant_type=authorization_code
            &code=<CODE>
            &redirect_uri=https://app.example.com/api/auth/infotrack/callback
            &code_verifier=<VERIFIER>

Send the resulting access token to the MCP endpoint as Authorization: Bearer <token>, and use the refresh token against the same token endpoint with grant_type=refresh_token before it expires.

An off-the-shelf MCP client can connect only if it lets you supply both a client_id and a client_secret that we issued.

Two constraints rule out some clients:

  • No Dynamic Client Registration. Our authorization server publishes no registration_endpoint, so a client that expects to register itself on first use cannot connect.
  • No public clients. The token endpoint accepts only client_secret_basic and client_secret_post. A client that performs PKCE without a secret will be rejected.

If your client meets both conditions, point it at the MCP endpoint for your environment and give it the ClientId, ClientSecret and scopes above. If you are not sure whether it does, tell us which client you are using and we will work it out with you.

Every filer needs their own account

Your OAuth client identifies your application. Each person filing through it still signs in as themselves.

The ClientId and ClientSecret we issue authenticate your application, not your users. On top of that, each person who files through your integration needs their own InfoTrack account, and signs in with it the first time they connect.

Why accounts can't be shared

A single shared login across your user base is technically possible and we would advise against it.

💡
An agent still files as a person

If your product files autonomously, the filing is still attributed to whichever user's account the token belongs to. Pick the user your agent is acting for and authorise as them, rather than creating a single service account for the whole firm.

Getting accounts set up

How your users get their accounts depends on how your integration is set up, so talk to us before you build a sign-up flow — we will tell you which route applies to you and give you the right link or process for your environment.

Bring the email addresses you want to use for testing. Test is a sealed environment and only addresses we have allowlisted can receive mail from it, so sign-up confirmations and notifications will not reach an address we do not know about.

Sending us your documents

You pass URLs, we fetch the bytes. Both the host and the file have to clear a few checks first.

Start_filing and Add_documents_to_filing take URLs to your documents. We fetch each one while the call is running and store our own copy, so the link only has to be valid for the duration of the request — a short-lived pre-signed URL is fine, and we will not come back for it later.

Documents already on InfoTrack storage are the exception: those are registered as-is rather than fetched and copied. That applies to files your users upload through one of our own surfaces, so in practice everything you send us from your own storage takes the fetch path described here.

Allowlist your document hosts first

We only fetch from hostnames we have been told about. Send us the hostnames you will serve documents from, for each environment, before you try an end-to-end test — otherwise every fetch is rejected and the filing cannot start.

Two things to check on your side:

Private storage with pre-signed links is the normal arrangement, and preferred — we do not need credentials, just a URL that resolves for as long as the call takes.

What we accept

KindExtensions
Documents.pdf
Images.jpg, .jpeg, .png, .tif, .tiff, .gif
Office.doc, .docx, .xls, .xlsx
Text.txt

Anything that is not already a PDF is converted before it reaches the court, so PDF is the path with the fewest moving parts — send PDFs where you have the choice.

⚠️
25 MB per document, and the court's limit is usually lower

25 MB is our ceiling, not a guarantee. Individual courts and electronic filing managers impose their own per-document and per-envelope limits on top of ours, and those are frequently tighter. A file that we accept can still be rejected downstream for size.

We check Content-Length before downloading and cap the stream as it copies, so a response that does not declare its length is still bounded. Redirects are followed within limits.

Everything litigation teams need to move a case forward

From filing and service to tracking — handled in one connected workflow.

⚖️

File court documents with confidence

Select the documents you want to file — one or many. InfoTrack prepares them to meet court requirements and submits them on your behalf.

  • ✓ Court-ready formatting handled automatically
  • ✓ Key details pulled from your documents
  • ✓ Submissions completed in minutes, not hours
📬

Request service without the back-and-forth

Order service of process directly from your documents. We coordinate delivery and keep you informed as it progresses.

  • ✓ Submit service requests in a few clicks
  • ✓ Track status without chasing vendors
  • ✓ Proof of service delivered when complete

The tools you see depend on your account

Your account type decides which tools appear in tools/list, so two partners connected to the same server can see different sets. If a tool below is missing from your session, that is why — tell us what you are trying to do rather than assuming it is unavailable.

The Elicitation column says whether a tool needs a client that supports MCP elicitation. Tools marked *Required* are hidden entirely from clients that do not advertise it.

Available to every account

These are visible whichever kind of account you connect with.

ToolWhat it doesElicitation
Add_service_contactAdds a service contact to the firm's address book.Required
Add_service_contact_with_detailsAdds a service contact from supplied details, without elicitation.—
Cancel_filingCancels a filing order while the court still allows it.—
Delete_attorneyRemoves an attorney from the firm's filing settings.—
Delete_service_contactRemoves a service contact from the firm's address book.—
Edit_attorneyUpdates an attorney's details in the firm's filing settings.—
Edit_service_contactUpdates a service contact's details.—
Get_attorneysLists the attorneys a filing can be made under.—
Get_available_filing_settingsLists what the account can file with — courts, attorneys and payment accounts.—
Get_filing_detailsReturns a filing order's status and details after submission, including any card refunds issued and whether the order can be refiled.—
Get_service_contactReturns a single service contact.—
Get_service_contactsLists the firm's service contacts.—
get_workflow_guidanceReturns guidance for the current session and which tool to start with.—

Filing and serving

The core filing workflow, available to both account types.

ToolWhat it doesElicitation
Add_attorney_with_detailsAdds a firm attorney from supplied details, without elicitation.—
Add_documents_to_filingAdds more documents to an in-progress filing draft.Required
cancel_serve_orderCancels an active serve order.—
Continue_filingContinues an existing filing workflow with updated information or confirmation.Required
Edit_filingEdits a saved draft. Called without an option it lists what can be changed; called with one it walks that change and saves the draft.Required
get_address_suggestionsReturns ranked address suggestions for validation.—
list_my_ordersLists the user's orders — filings, serves and other services — with status, including drafts.—
Refile_filingResubmits a filing the court rejected, carrying over only the rejected items. Not available at every court — check CanRefile on Get_filing_details first.Required
remove_attorneyRemoves an attorney from a serve order.—
Schedule_hearingHearing-date scheduling is available when the filing result supports it.Required
send_job_messageSends a message related to an existing serve job (after order creation/submission).—
Start_filingInitiates a new court filing with PDF documents. Extracts case information and calculates filing fees.Required

InfoTrack Assistant accounts

Additional tools for accounts on the InfoTrack Assistant surface.

ToolWhat it doesElicitation
Add_attorneySelects a firm attorney (elicitation clients only; repeatable for multiple attorneys, required for CA cases).Required
add_documents_to_serveAdds documents to a serve order already in progress, without re-reading the ones already attached.—
add_recipientAdds a recipient when automated extraction misses them; address is optional.—
adjust_recipient_documentsUpdates document assignments for specific recipients.—
configure_registered_agentConfigures registered-agent serving for organization recipients.—
confirm_ordersConfirms the selections and places the orders, after the user has explicitly confirmed in chat.Not supported
get_orders_needing_attentionLists serve orders that require user action (proof review, messages, or follow-ups).—
get_proof_of_serviceReturns the proof of service for a completed serve order.—
get_serve_order_detailsRetrieves details for an existing serve order.—
initiate_serveAsks for the matter, state and documents needed, then hands off to initiate_serve_with_details.Not supported
initiate_serve_intakePrimary intake tool. Collects missing matter/state via elicitation, requires uploaded documents, and runs extraction.Required
initiate_serve_with_detailsStarts a service-of-process order from a supplied matter, state and documents, and returns the recipients and options found.Not supported
prepare_skip_traceEstimates skip-trace fees for recipients without a usable address, and attaches your selections to the order.—
present_orders_for_confirmationPresents structured confirmation and creates orders (elicitation clients only).Required
remove_recipientRemoves a recipient from a serve order. The last remaining recipient cannot be removed.—
remove_skip_traceRemoves one or more recipients from skip trace selections (does not remove recipients).—
search_integrated_documentsSearches documents in a connected practice-management system. Requires a mappingId.—
select_firm_contactsSelects firm contacts, then selects notification recipients from the chosen subset (elicitation clients only; at least one contact required).Required
select_serve_optionsSelects SLA and agency per recipient and returns fee estimates (does not place orders).—
set_recipient_nameSets or corrects a recipient's name; required before a nameless recipient can be served.—
set_recipient_typeSwitches a recipient between individual and organization.—
update_recipient_addressUpdates a recipient's address and refreshes available options (can use PlaceId from get_address_suggestions).—

Courtny accounts

Additional tools for accounts on the Courtny surface.

ToolWhat it doesElicitation
add_documents_to_serve_courtnyAdds documents to a serve order already in progress, without re-reading the ones already attached.—
add_recipient_courtnyAdds a recipient when automated extraction misses them; address is optional.—
Add_userCreates a user on the account.Required
adjust_recipient_documents_courtnyUpdates document assignments for specific recipients.—
configure_registered_agent_courtnyConfigures registered-agent serving for organization recipients.—
create_support_ticketRaises a support request via the Courtny client server; withholds creation when likely duplicates exist.—
Delete_draft_filingDeletes a saved draft filing that was never submitted.—
Delete_userRemoves a user from the account.—
Get_account_settingsReturns the account's current settings.—
get_orders_needing_attention_courtnyLists serve orders that require user action (proof review, messages, or follow-ups).—
get_proof_of_service_courtnyReturns the proof of service for a completed serve order, with a downloadable link.—
get_serve_order_details_for_courtnyRetrieves details for an existing serve order.—
get_support_guidanceReturns answers to common support questions, so the agent can resolve them before raising a ticket.—
get_ticket_statusLists the user's support requests with customer-facing statuses and full threads.—
initiate_file_and_serve_courtnyStarts a combined court filing and service-of-process order from uploaded documents.—
initiate_serve_courtnyStarts a service-of-process order and prompts for the matter, state and documents it still needs.—
initiate_serve_courtny_with_detailsStarts a service-of-process order from a supplied matter, state and documents, and returns the recipients and options found.—
List_usersLists the users on the account.—
remove_recipient_courtnyRemoves a recipient from a serve order. The last remaining recipient cannot be removed.—
reply_to_support_ticketAdds a user message to an existing support request by reference.—
Reset_user_passwordSends a password reset to a user.—
select_serve_options_courtnySelects SLA and agency per recipient and returns fee estimates (does not place orders).—
set_recipient_name_courtnySets or corrects a recipient's name; required before a nameless recipient can be served.—
set_recipient_type_courtnySwitches a recipient between individual and organization.—
submit_file_and_serve_courtnyConfirms and submits a prepared file-and-serve order.Required
submit_orders_courtnyConfirms and submits the prepared serve orders.Required
Update_account_settingsUpdates the account's settings.—
update_recipient_address_courtnyUpdates a recipient's address and refreshes available options (can use PlaceId from get_address_suggestions).—
update_recipient_contact_courtnyUpdates a recipient's contact details.—
Update_userUpdates a user's details.—

A small number of internal and demo tools are not listed here and are not part of the supported partner surface.

From documents to done in seconds

Watch how your AI agent handles a complete court filing workflow — extraction, validation, fee calculation, and submission — all without leaving the conversation.

⚖️

Complete Court Filing Flow

👤
You
I want to start a filing.
✨
AI Agent
To start a new eFiling, I'll need at least one PDF to upload. Please attach them in the prompt and then we can start!
👤
You
📄 NuecesCountyStandingOrders_1.pdf
📄 Original_Petition_for_Divorce.pdf
📄 Process_Request_Form.pdf
📄 Notice_of_Hearing.pdf
✨
AI Agent
Starting filing — Calculating filing fees...
✓ Called Start_filing with 4 PDFs
✓ Extracted case information from documents
✓ Calculated filing fees
✨
AI Agent

Please review the following summary for your filing:

Case information

  • • State: TX
  • • Matter: Smith v. Smith
  • • Location: Nueces County - District Court
  • • Case category: Family - Marriage Relationship
  • • Case type: Divorce No Children

Filings (4)

Filing #1: Petition

  • • Description: Nueces County Standing Order Regarding Children, Property And Conduct Of The Parties
  • • Lead document: NuecesCountyStandingOrders_1.pdf
  • ○ Security level: Does not contain sensitive data

Filing #2: Petition

  • • Description: Original Petition For Divorce
  • • Lead document: Original_Petition_for_Divorce.pdf
  • ○ Security level: Does not contain sensitive data

Filing #3: Application

  • • Description: Nueces County Process Request Sheet
  • • Lead document: Process_Request_Form.pdf
  • ○ Security level: Does not contain sensitive data

Filing #4: Application

  • • Description: Notice Of Hearing
  • • Lead document: Notice_of_Hearing.pdf
  • ○ Security level: Does not contain sensitive data

Case parties (3)

  • • Jane Smith
    Party type: Petitioner
  • • John Smith
    Party type: Respondent
  • • Sarah Johnson
    Party type: Attorney

Filing information

  • • Filing party: Jane Smith
  • • Filer type: Not Applicable
  • • Payment account: Waiver

Filing fee summary

  • • Total cost: $70.00

Do you want to proceed with this filing in TX?

👤
You
Yes, submit the filing
✨
AI Agent
Submitting your filing...
✓ Called Continue_filing with confirmation
✓ Filing submitted to court
✓ Confirmation received
✨
AI Agent
Filing Submitted Successfully

Your court filing has been submitted to Nueces County District Court.

Matter: Smith v. Smith

Documents: 4 PDFs submitted

Status: Pending court acceptance

Total Cost: $70.00

Receive order updates by webhook

If you submit filings through the InfoTrack MCP tools, you can receive order updates for every filing your users place — delivered to one endpoint, for all of your users, via a webhook.

①

Create a mapping

POST a ClientReference and a RetailerReference, and receive a mappingId.

②

Pass the mappingId

Hand it to the MCP filing tools so each filing is tagged with your reference.

③

Receive updates

Correlate every order update back to your user/matter using the RetailerReference.

Your app InfoTrack Your webhook 1 · create mapping mappingId 2 · file with mappingId processes the order 3 · signed POST — OrderDto carries X-InfoTrack-Signature 200 OK retried a few times if no 2xx · at-least-once
InfoTrack calls your endpoint on each material order update — asynchronously and at-least-once. Verify the HMAC signature, dedupe on OrderId, and apply updates in SequenceNumber order.

Prerequisites

Access token. You already authenticate to InfoTrack to call the MCP tools. The same Authorization: Bearer <ACCESS TOKEN> is used to create a mapping.

Webhook endpoint and reference prefix. To receive order updates you must give us an endpoint to POST to, and InfoTrack will assign you a reference prefix (e.g. Novo_). We register both during onboarding. Every RetailerReference you send (see Step 1) must begin with this prefix — that's what routes your updates to your endpoint.

🔒
Deliveries are HMAC-signed

Every delivery carries an HMAC signature you can verify to confirm it genuinely came from InfoTrack and that the body wasn't tampered with — see Verifying deliveries.

Step 1 — Create a mapping

POST a ClientReference and a RetailerReference to the secure/api/v1/mapping endpoint.

POST /secure/api/v1/mapping
POST /secure/api/v1/mapping HTTP/1.1
Host: testsearch.infotrack.com
Authorization: Bearer <ACCESS TOKEN>
Content-Type: application/json

{
    "ClientReference": "01232X - Novo",
    "RetailerReference": "Novo_a1b2c3d4"
}

Response

200 OK
{
    "Token": "54a93e46-a103-41e9-8139-db67efa6ad7a",
    "MappingId": "6c82af0c-01c6-467d-ab38-861ba8a919f3",
    "Url": "https://testintegrated.infotrack.com/menu?tokenId=…&mappingId=6c82af0c-01c6-467d-ab38-861ba8a919f3&retailerReference=Novo_a1b2c3d4"
}

You only need the MappingId. (The Token and Url are for browser-based integrated sessions and aren't needed here.)

A mappingId is reusable and carries a single RetailerReference. Most integrators create one mapping per matter and reuse its mappingId for every filing in that matter, but per-filing works too — it's up to you. There is no rate limit on creating mappings.

Example

CreateMappingAsync.cs
private static async Task<string> CreateMappingAsync(Uri host, string clientReference, string retailerReference, string accessToken)
{
    var matterDetail = new
    {
        ClientReference = clientReference,
        RetailerReference = retailerReference
    };

    using var client = new HttpClient();
    var builder = new UriBuilder(host) { Path = "secure/api/v1/mapping" };

    using var req = new HttpRequestMessage(HttpMethod.Post, builder.Uri);
    req.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
    req.Content = new StringContent(JsonSerializer.Serialize(matterDetail), Encoding.UTF8, "application/json");

    using var resp = (await client.SendAsync(req)).EnsureSuccessStatusCode();
    var json = await resp.Content.ReadAsStringAsync();
    return JsonSerializer.Deserialize<Mapping>(json).MappingId;
}
createMapping.js
const createMappingAsync = async (host, clientReference, retailerReference, accessToken) => {
    const url = new URL(host);
    url.pathname = 'secure/api/v1/mapping';

    const resp = await fetch(url.toString(), {
        method: 'POST',
        headers: {
            'Authorization': `Bearer ${accessToken}`,
            'Content-Type': 'application/json'
        },
        body: JSON.stringify({ ClientReference: clientReference, RetailerReference: retailerReference })
    });

    if (!resp.ok) {
        throw Error(`Error (${resp.status}) ${resp.statusText}`);
    }

    const mapping = await resp.json();
    return mapping.MappingId;
};

Step 2 — Pass the mappingId to the MCP filing tools

The InfoTrack MCP filing tools accept an optional mappingId parameter:

Pass the MappingId from Step 1. When a mappingId is supplied, the MCP server resolves the mapping and applies:

⚠️
No mappingId, no update

If you don't pass a mappingId, the order is placed without your retailer reference and no order update will be dispatched to your webhook.

Step 3 — Receive order updates

Whenever a material order update occurs, we POST the full order to your registered endpoint as JSON. As is common with webhooks, you may receive duplicate updates and they can arrive out of order — treat delivery as at-least-once: dedupe on OrderId and apply updates in SequenceNumber order. If your endpoint is briefly unreachable we retry the delivery a few times before parking it for recovery.

To tie an update back to the user and matter that placed it, read the RetailerReference (your prefixed value, e.g. Novo_a1b2c3d4) and the OrderId.

Verifying deliveries

Every request carries an HMAC signature so you can confirm a delivery genuinely came from InfoTrack and that the body wasn't tampered with. Verify it before trusting the payload — especially the status.

We sign each delivery with a shared secret provided to you during onboarding, and send:

Delivery request header
X-InfoTrack-Signature: t=<unix-timestamp>,v1=<hex>

To verify:

  1. Read t and v1 from the header.
  2. Compute HMAC-SHA256(secret, "{t}.{rawBody}") over the raw body — before any JSON parsing or re-serialization.
  3. Compare your result to v1 using a constant-time comparison.
  4. Reject the request if it doesn't match, or if t is older than your tolerance (e.g. 5 minutes) — this guards against replay.
IsValidSignature.cs
bool IsValidSignature(string rawBody, string signatureHeader, string secret)
{
    var parts = signatureHeader.Split(',')
        .Select(p => p.Split('=', 2))
        .ToDictionary(p => p[0], p => p[1]);

    // Reject stale deliveries (replay protection)
    if (Math.Abs(DateTimeOffset.UtcNow.ToUnixTimeSeconds() - long.Parse(parts["t"])) > 300)
        return false;

    using var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(secret));
    var computed = Convert.ToHexString(
        hmac.ComputeHash(Encoding.UTF8.GetBytes($"{parts["t"]}.{rawBody}"))).ToLowerInvariant();

    return CryptographicOperations.FixedTimeEquals(
        Encoding.UTF8.GetBytes(computed), Encoding.UTF8.GetBytes(parts["v1"]));
}
isValidSignature.js
const crypto = require('crypto');

function isValidSignature(rawBody, signatureHeader, secret) {
    const { t, v1 } = Object.fromEntries(signatureHeader.split(',').map(p => p.split('=')));

    // Reject stale deliveries (replay protection)
    if (Math.abs(Math.floor(Date.now() / 1000) - Number(t)) > 300) return false;

    const computed = crypto.createHmac('sha256', secret).update(`${t}.${rawBody}`).digest('hex');
    const a = Buffer.from(computed);
    const b = Buffer.from(v1);
    return a.length === b.length && crypto.timingSafeEqual(a, b);
}

Data model

Fees arrive as pre-formatted currency strings (not numbers) — each fee is exposed as three keys: the base amount (ex-GST), its …GST, and its …Total (inc GST). Dates arrive as ISO-8601 UTC strings.

OrderUpdate.cs
public class OrderUpdate
{
    public bool AvailableOnline { get; set; }
    public string BillingTypeName { get; set; }
    public string ClientReference { get; set; }
    public string Comments { get; set; }
    public string DateOrdered { get; set; }     // ISO-8601 UTC, e.g. "2026-07-01T14:03:22.0000000Z"
    public string DateCompleted { get; set; }   // ISO-8601 UTC; null until completed
    public string Description { get; set; }
    public int OrderId { get; set; }
    public string OrderedBy { get; set; }
    public int ParentOrderId { get; set; }
    public string Reference { get; set; }
    public string RetailerReference { get; set; }
    public string RetailerFee { get; set; }        // pre-formatted currency string, e.g. "10.00"
    public string RetailerFeeGST { get; set; }
    public string RetailerFeeTotal { get; set; }
    public string SupplierFee { get; set; }
    public string SupplierFeeGST { get; set; }
    public string SupplierFeeTotal { get; set; }
    public string TotalFee { get; set; }
    public string TotalFeeGST { get; set; }
    public string TotalFeeTotal { get; set; }      // total disbursement (inc GST)
    public string ServiceName { get; set; }
    public string Status { get; set; }
    public string DisplayStatus { get; set; }
    public string StatusMessage { get; set; }
    public string DownloadUrl { get; set; }        // merged single-PDF link for the order
    public string OnlineUrl { get; set; }          // link to view the order on the InfoTrack platform
    public string Email { get; set; }
    public string ServiceIdentifier { get; set; }
    public int ClientId { get; set; }
    public int LoginId { get; set; }
    public long SequenceNumber { get; set; }
    public IReadOnlyList<OrderFile> Files { get; set; }
}
OrderFile.cs
public class OrderFile
{
    public string Url { get; set; }        // direct storage link to the individual document
    public string Name { get; set; }       // best-effort; null when InfoTrack has no file name
    public string Extension { get; set; }  // best-effort; derived from Name; null when Name is null
}

Field reference

These are the fields relevant to a webhook consumer. Any field not listed here (e.g. SecureUrl, FileHash, IsBillable) is for InfoTrack internal use and can be ignored.

FieldDescription
OrderIdInfoTrack's unique id for the order. Multiple updates arrive for the same order, so dedupe on OrderId before you insert/update, and use SequenceNumber to apply them in order.
SequenceNumberA strictly-increasing value stamped on each update for an order. Keep the highest SequenceNumber you've applied per OrderId and ignore any update with a lower or equal value — this prevents a late-arriving stale update (e.g. a Pending) from overwriting a newer one (e.g. a Complete).
ParentOrderIdRelates this order to a parent order. 0 means it has no parent. See Orders, envelopes, and filings below.
RetailerReferenceYour prefixed correlation token (the value you sent on the mapping, beginning with your InfoTrack-assigned prefix). Use it to tie the order back to your user and matter.
ClientReferenceThe matter reference you supplied on the mapping.
StatusThe order's lifecycle status (e.g. Saved, Pending, Complete, Error) — where the order is in processing.
DisplayStatusThe outcome shown to users (e.g. Accepted, Rejected, Partially Rejected / Partially Accepted, Return For Correction, Served, In Progress). For court filings this is the court's verdict, and it is distinct from Status: a filing can be Status: Complete while DisplayStatus is Accepted or Rejected. Use DisplayStatus (not Status) to tell an accepted filing from a rejected one, and to surface the outcome to your users.
StatusMessageHuman-readable detail accompanying the current status.
DescriptionThe best human-readable description of what was ordered/filed.
ServiceNameThe order type name (e.g. New Case Filing, Filing).
ServiceIdentifierShort machine identifier for the service (e.g. ILNewCaseFiling).
CommentsOrder-related information from InfoTrack.
DateOrderedWhen the order was placed (ISO-8601 UTC string).
DateCompletedWhen the order reached a completed status (ISO-8601 UTC string; null until then).
ReferenceService/court reference for the order.
OrderedByUsername of the InfoTrack user who placed the order.
EmailEmail address of the user who placed the order.
ClientIdInfoTrack client id — useful for grouping updates by client.
LoginIdInfoTrack login id — useful for linking updates to a specific user.
RetailerFee* / SupplierFee* / TotalFee*Fee breakdown as pre-formatted currency strings (e.g. "10.00"). Each is three keys: the base amount ex-GST (e.g. RetailerFee), its GST (RetailerFeeGST), and its inc-GST total (RetailerFeeTotal). TotalFeeTotal is the total disbursement.
AvailableOnlineWhether the order can be viewed on the InfoTrack website.
BillingTypeNameBilling/product type for the order.
DownloadUrlMerged single-PDF link for the order's documents. Per-document links are on Files[].
OnlineUrlLink to view the order on the InfoTrack platform.
FilesDocuments associated with the order, each with a Url (direct storage link to that document) plus best-effort Name and Extension. Name/Extension are null when InfoTrack has no file name for the document, so fall back to Url to tell documents apart. For filings this includes the court-stamped / returned documents once the court accepts. Populated only for statuses where documents are ready; otherwise an empty list.

Order status: Status (lifecycle) vs DisplayStatus (outcome)

Status tells you where the order is in processing; DisplayStatus tells you the outcome. For court filings the court's decision is in DisplayStatus, not Status — and an order placed through the MCP tools is marked Status: Complete even when the court rejects it or returns it for correction.

⚠️
Always read DisplayStatus for the result

Never treat Status: Complete as "accepted." A filing is Status: Complete whether the court accepted, rejected, or returned it — the verdict is in DisplayStatus.

Status values (Filing & Service of Process)

StatusTerminal?Meaning
SavednoDraft saved, not yet submitted.
To Be RequestednoCreated, queued for processing.
QueuednoQueued to be sent.
PendingnoSubmitted, awaiting an outcome (usually DisplayStatus: In Progress).
Submitting / Submitted / Under ReviewnoIn submission / under review.
CompleteyesTerminal — the order finished, including filings the court rejected or returned for correction. Check DisplayStatus for the result.
ErroryesTerminal — a technical failure (not a court rejection).
CanceledyesTerminal — the order was cancelled.

DisplayStatus values

💡
Recommended handling

Treat a Status of Complete, Error, or Canceled as terminal, then branch on DisplayStatus. Filing: Accepted / Served = success; Rejected / Partially Rejected / Partially Accepted / Return For Correction / Failed = surface to the user; In Progress / empty = not yet decided. Service of Process: Complete - Service = served; Complete - Non-service / Complete - Bad Address = surface to the user; the Awaiting … / Proof … Needs Review states = still in progress.

Orders, envelopes, and filings

In InfoTrack, everything is an order, and a single court e-filing submission produces several related orders linked by ParentOrderId:

You'll receive updates for both the envelope and each of its filings; group them by ParentOrderId to reconstruct the submission. For example, a new-case submission with one document produces an envelope order (ServiceName: New Case Filing, ParentOrderId: 0) and a child filing order (ServiceName: Filing, ParentOrderId = the envelope's OrderId).

The filing tools (Start_filing / Continue_filing) return this envelope-level OrderId (as DraftOrderId / FiledOrderId), and only the envelope-level id. It matches the envelope order's OrderId on the webhook, so store it and correlate updates back to the filing you started; the individual filing(s) arrive on the webhook with their own OrderId and a ParentOrderId set to the envelope's id.

ℹ️
Court filing only

This envelope/filing structure applies to court filing only — it does not apply to process serving orders.

Example receiver

OrderUpdatesController.cs
[ApiController]
[Route("[controller]")]
public class OrderUpdatesController : ControllerBase
{
    private readonly IInfoTrackRepository _repo;
    private readonly ILogger _logger;

    public OrderUpdatesController(IInfoTrackRepository repo, ILogger<OrderUpdatesController> logger)
    {
        _repo = repo;
        _logger = logger;
    }

    [HttpPost]
    [Route("")]
    public IActionResult Create(OrderUpdate order)
    {
        if (order == null)
        {
            return BadRequest("Missing order update dto body");
        }

        // Correlate back to your user/matter using order.RetailerReference (your prefixed value).
        _logger.LogInformation("Received update for order {OrderId} ({RetailerReference})",
            order.OrderId, order.RetailerReference);

        _repo.AddOrder(order);
        return Ok();
    }
}

Summary

StepWhat you send / receiveKey value
Create mappingPOST ClientReference + RetailerReferencereturns MappingId
Place filingcall MCP filing tools with mappingIdorder tagged with your prefixed RetailerReference
Order updatesfull order POSTed to your webhookcorrelate via RetailerReference