Casepoint
Casepoint connects your legal and investigative data to ChatGPT. Ask questions about active matters across eDiscovery, Legal Hold, and FOIA, and get clear answers drawn directly from your Casepoint workspace or organization. Check review status, hold status and rosters, and FOIA deadlines without opening the platform. Access is read-only and scoped to what you select when you connect.
- Integration type
- Plugin
- Verification status
- Not applicable
- Platform
- ChatGPT
- Primary Subcategory
- Legal Practice & Matter Platforms
- Secondary Subcategories
- None listed
- Brand
- Casepoint
- Access
- Account required
- First tracked
- 2026-08-01
- Tool count
- 14
- Geography
- US
The Primary Subcategory used for this profile’s headline score.
Other Subcategories where the Integration is visible.
ChatGPT Plugin Discoverability Score
ChatGPT organic discovery is not live yet
Casepoint is tracked in the ChatGPT Plugin registry. Public organic-discovery measurement is not live for ChatGPT yet, so there is no score to publish today.
Get notified when your score goes live
Enter your work email and we’ll notify you when ChatGPT Plugin organic discovery scoring launches.
No spam. Unsubscribe any time.
Competing in ChatGPT Legal Practice & Matter Platforms
View CategoryHow the Discoverability Score works
Organic discovery scoring for Casepoint on ChatGPT is not live yet. The score will use measured agent conversations when it launches.
Organic discovery scoring is pending. Your Plugin score will appear on this scale when measurement goes live.
FoundDiagnostic
Whether Claude found your Plugin in connector search. It must be Found before it can reach the picker, but the score counts picker appearances—not search results.
PickedMain score
How often your Plugin appeared in the picker, or Claude invoked it directly, across contested conversations. This percentage is the Discoverability Score; the headline number is rounded.
PositionedDiagnostic
What position your Plugin appeared in when it was shown in the picker. This shows prominence, but it does not affect the score.
14 tools agents can invoke
OUTPUT FORMAT — READ FIRST ══════════════════════════ Present results as concise Markdown tables; never paste raw JSON. Render zero counts as "0"; missing avg-days as "—". Use EXACTLY these column headers (copy character-for-character): component_abbreviation → "Agency/Component" total_requests_received → "Total Requests Received" total_requests_closed → "Total Requests Closed" fee_waivers_granted → "Fee Waivers Granted" fee_waivers_denied → "Fee Waivers Denied" avg_processing_days_simple → "Avg Processing Days (Simple)" avg_processing_days_complex → "Avg Processing Days (Complex)" avg_processing_days_expedited → "Avg Processing Days (Expedited)" avg_processing_days → "Avg Processing Days" previous_fy_backlogged_requests → "Previous Fiscal Year Backlogged Requests" current_fy_backlogged_requests → "Current Fiscal Year Backlogged Requests" fiscal_year → "Fiscal Year" (caption/heading — NOT a column) USE EXACT HEADERS — DO NOT PARAPHRASE, ABBREVIATE, OR REWORD ══════════════════════════════════════════════════════════════ Copy header strings character-for-character — capitalization, parentheses, spacing. Do NOT expand "Avg" to "Average", swap parentheses for colons, or add/drop words. FORBIDDEN variants: "Requests received", "Fee waivers granted", "Avg processing days (simple)", "Average Processing Days", "Backlog", "Current Year Backlogged", "Total Received". PURPOSE ═══════ Returns FOIA Annual Report aggregate metrics for a fiscal year, broken out by Agency/Component. All three families — FOIA, Appeal, Consultation — are always returned in a single call. Call this tool ONCE; no routing or multi-call logic is needed. AGENCY/COMPONENT DIMENSION ══════════════════════════ Every row carries a `component_abbreviation` (the short code, e.g. "NE"). Render it VERBATIM in the "Agency/Component" column — never use the full component name. Rows are per component. The default (no `component` argument) returns EVERY reportable component, each on its own row. When the user names one or more components, pass them via the `component` argument (comma-separated abbreviations, exact/case-insensitive); only those components' rows come back. AGENCY OVERALL ROW: Each family includes a synthetic total row with `component_abbreviation = "Agency Overall"` — the agency-wide roll-up. Render it as the LAST row in each family table. Do NOT drop it or move it. ROUTING — USE request_type_name FOR GROUPING ONLY, NEVER RENDER AS A COLUMN ═════════════════════════════════════════════════════════════════════════════ The response's `by_request_type` list contains rows for all three families. Each row has a `request_type_name` field — use it ONLY to route each row to the correct table: • "FOIA" → "### FOIA" table • "Appeal" → "### Appeal" table • "Consultation" → "### Consultation" table Do NOT render `request_type_name` as a column. It is internal routing data. THREE TABLES — ALWAYS, IN THIS ORDER ═════════════════════════════════════ Always produce exactly THREE separate Markdown tables, each with its own heading. Place "Fiscal Year: <value>" as a caption ABOVE the tables. 1. ### FOIA 2. ### Appeal 3. ### Consultation COLUMN SETS (fixed per family — never add or remove columns) ══════════════════════════════════════════════════════════════ ### FOIA — exactly 10 columns, in this order: (1) Agency/Component (2) Previous Fiscal Year Backlogged Requests (3) Total Requests Received (4) Total Requests Closed (5) Fee Waivers Granted (6) Fee Waivers Denied (7) Avg Processing Days (Simple) (8) Avg Processing Days (Complex) (9) Avg Processing Days (Expedited) (10) Current Fiscal Year Backlogged Requests ### Appeal — exactly 6 columns, in this order: (1) Agency/Component (2) Previous Fiscal Year Backlogged Requests (3) Total Requests Received (4) Total Requests Closed (5) Avg Processing Days (6) Current Fiscal Year Backlogged Requests NO fee-waiver columns. NO per-track Avg Processing Days columns. ### Consultation — exactly 3 columns, in this order: (1) Agency/Component (2) Total Requests Received (3) Total Requests Closed NO Backlogged Requests columns (DOJ does not track Backlogged Consultations). NO Avg Processing Days. NO Fee Waivers. HARD CONSTRAINTS — VIOLATIONS ARE REJECTED ═══════════════════════════════════════════ 1. NEVER render `request_type_name` as a column — it is routing data only. 2. NEVER emit ONE combined table with families as rows and metrics as columns. 3. NEVER pivot into a Metric/Value layout — rows are components, columns are metrics. 4. NEVER drop columns because values are zero or missing — render "0" (counts) or "—" (avg-days with no eligible closed rows). 5. NEVER reorder columns. 6. ALWAYS render the "Agency Overall" row LAST in each family table. 7. The FOIA table has EXACTLY 10 columns — no more, no less. 8. The Appeal table has EXACTLY 6 columns — no more, no less. 9. The Consultation table has EXACTLY 3 columns — no more, no less. 10. Each COLUMN is its OWN Markdown column with its OWN header cell. "Fee Waivers Granted" and "Fee Waivers Denied" are TWO separate columns. "Avg Processing Days (Simple)", "(Complex)", "(Expedited)" are THREE separate columns for FOIA. Forbidden layout (pivoted families as rows): | Metric | FOIA | Appeal | Consultation | |---------------------|------|--------|--------------| | Requests received | 593 | 69 | 26 | Forbidden layout (pivoted Metric/Value): | Metric | Value | | Requests received | 593 | CONCRETE LAYOUT STRUCTURE (copy this shape, substitute actual values) ══════════════════════════════════════════════════════════════════════ ### FOIA | Agency/Component | Previous Fiscal Year Backlogged Requests | Total Requests Received | Total Requests Closed | Fee Waivers Granted | Fee Waivers Denied | Avg Processing Days (Simple) | Avg Processing Days (Complex) | Avg Processing Days (Expedited) | Current Fiscal Year Backlogged Requests | |------------------|------------------------------------------|-------------------------|-----------------------|---------------------|--------------------|------------------------------|-------------------------------|---------------------------------|------------------------------------------| | <abbr> | <prev_backlog> | <received> | <closed> | <granted> | <denied> | <avg_s> | <avg_c> | <avg_e> | <curr_backlog> | | Agency Overall | <prev_backlog> | <received> | <closed> | <granted> | <denied> | <avg_s> | <avg_c> | <avg_e> | <curr_backlog> | ### Appeal | Agency/Component | Previous Fiscal Year Backlogged Requests | Total Requests Received | Total Requests Closed | Avg Processing Days | Current Fiscal Year Backlogged Requests | |------------------|------------------------------------------|-------------------------|-----------------------|---------------------|------------------------------------------| | <abbr> | <prev_backlog> | <received> | <closed> | <avg> | <curr_backlog> | | Agency Overall | <prev_backlog> | <received> | <closed> | <avg> | <curr_backlog> | ### Consultation | Agency/Component | Total Requests Received | Total Requests Closed | |------------------|-------------------------|-----------------------| | <abbr> | <received> | <closed> | | Agency Overall | <received> | <closed> | NOTES (always append after the tables) ═══════════════════════════════════════ Always append a "Notes" section below the tables: • "The FOIA rows include Privacy Act (PA), Combined FOIA and PA, and every FOIA-derived custom request type in their counts." • "The Appeal rows include every Appeal-derived custom request type in their counts." • "Consultation has no derived custom types — its numbers are the base type alone." • "Fiscal year runs Oct 1 – Sep 30. Figures come from the CP FOIA annual-report pre-aggregated tables and match the corresponding DOJ FOIA Annual Report sections." VALUE RENDERING ═══════════════ Render every value EXACTLY as it appears — do NOT sanitize, truncate, or replace. `component_abbreviation` can contain any character — put it in the cell unchanged. Escape Markdown-active characters that would break the table (a pipe `|` → `\|`). Do NOT show request_type_id or component_id anywhere — not in cells, columns, footnotes, or legends. WHAT THIS TOOL COUNTS ═════════════════════ Metrics come from pre-aggregated CP FOIA annual-report tables: • Total received and total closed — all three families • Fee waivers granted / denied — FOIA family only • Avg processing days per track (Simple / Complex / Expedited) — FOIA family • Avg processing days (overall) — Appeal family • Current / Previous Fiscal Year Backlogged Requests — FOIA and Appeal families (Consultation excluded) Tasks and Reports are never counted. Litigation is excluded entirely. Row ordering: components sorted by creation order (c_componentid ASC); "Agency Overall" last. Inputs: - fiscal_year — 4-digit fiscal year (e.g. 2026). Optional — defaults to the current federal fiscal year (Oct 1 – Sep 30). FISCAL YEAR CALL RULE: Make ONE call per fiscal year. • User specifies a year ("2025 annual report", "FY2024 data") → call once with that year. Do NOT also call for the current FY. • User says "current year" or omits a year → omit fiscal_year (defaults to current FY). Do NOT guess or supply a year. • User explicitly asks for multiple years → make one sequential call per year, presenting results year by year. Never combine years into a single call. - component — Agency/Component filter by component ABBREVIATION (short code, e.g. "NE"), matched EXACTLY and case-insensitively — NOT the full component name. Pass a single abbreviation or a comma-separated list ("NE, SW"). OMIT (or pass empty) to get EVERY component (one row per component, the default). Unknown abbreviations return no rows for that abbreviation. ERROR RESPONSES ═══════════════ When the report cannot be produced (fiscal year out of range, component too long, backend timeout, etc.), the tool surfaces a single message. Present it as plain text (do not wrap in a JSON block) and do not retry unchanged. SELF-CHECK before emitting the answer: 1. Did I call this tool ONCE? (Single call always — no routing needed.) 2. Did I use `request_type_name` ONLY to group rows into the three tables, not render it? 3. Are the FOIA / Appeal / Consultation tables each under their own "### " heading? 4. Does FOIA have exactly 10 columns? Appeal 6? Consultation 3? 5. Did I drop any column because values are all zero? Put it back with "0". 6. Is "Agency Overall" the last row in each family table? 7. Am I emitting a pivoted Metric/Value layout? Replace it with the column-per-metric layout. The first column in every table is ALWAYS "Agency/Component". Do NOT add "Request Type" as a column — it was deliberately removed. Do NOT add any column not listed in the family's declared set above.
get_annual_report
Custodian collection report for the connected eDiscovery workspace, grouped by custodian. Returns one entry per custodian (titled by custodian email) with the custodian-level roll-up — total documents collected, the data sources covered (email, OneDrive, Teams, Slack, mobile, archived mailboxes, shared drives, …), the collected data volume (GB/TB), and the file types collected — PLUS a per-datastore breakdown under "Data Stores": one entry per datastore the custodian has documents in, each carrying that datastore's own document count, date range, data sources, collected volume, and file types. Every custodian is returned even with no collected documents (empty breakdown). Use this when the user asks things like: "custodian collection report", "what did we collect per custodian", "collection volume by custodian", "data sources per custodian", "how much did each custodian contribute per datastore", "per-datastore breakdown by custodian". The optional date range filters by the collected document date; omit for all time.
get_custodian_collection_summary
The people (custodians) placed on ONE named legal hold — the hold's roster — including each person's directory information and hold-notification status, plus any custom fields configured for custodians (under customFields). Pass the exact hold name from get_legalhold_list. This tool returns each custodian's hold-notification status — whether they were added to the hold, notified (notice sent), and how they responded. A custodian is "on a legal hold" when they appear on the hold's roster (any HoldStatus value). CUSTODIAN HOLD STATUSES — meanings: • added — placed on the hold roster; no notice has been sent yet • sent — a hold notice was delivered to the custodian; awaiting their response • accepted — the custodian acknowledged and accepted the hold notice • rejected — the custodian declined / rejected the hold notice • released — the custodian has been removed from the hold • silent — added to the hold without any notice being sent (silent hold) CRITICAL DISTINCTION — hold-notification status ≠ data-preservation status: • HoldStatus (this tool) tracks whether the custodian was notified about the hold. A custodian with status 'accepted' has acknowledged the notice — this does NOT mean their data is preserved. • PreservationStatus (use get_legalhold_preservation_collections) tracks whether the custodian's actual data (emails, files, chats) is being preserved in the cloud system. Do NOT use this tool to answer questions about data preservation progress. PAGINATION RULES — follow strictly: • Sequential only. Start with navigate='first'. To move forward, call again with navigate='next' and current_page set to the 'page' value from the previous response; navigate='previous' goes back one step. You can move only ONE step at a time and CANNOT jump to an arbitrary page. • If the user asks for a specific page ("give me page 3", "go to page 5", "show page -1"), do NOT attempt it. Respond: "I can only move to the next or previous set of records, not jump directly to a specific page. Would you like me to continue with the next set?" • NEVER expose page structure to the user — no page numbers, no "page 1 of 3", no "more pages", no total page/record counts. The 'page' value is for your internal use as current_page only. • If hasMore=true, end with a simple offer and nothing more: "Would you like me to show the next set of records?" If hasMore=false, tell the user this is the end of the list and do NOT offer a next set. • Never pass a raw user-supplied page number into this tool. Pick a different tool when: the user wants ALL custodians org-wide (use get_people), or the hold's settings/roles rather than its people (use get_legalhold_details). RESPONSE PRESENTATION — how to show this result to the user: • The result is JSON for YOU to read; do NOT paste or display the raw JSON to the user. • Present results as a concise Markdown table/summary. • Keep the answer concise and human-readable, and offer to show more detail on request.
get_legalhold_custodians
Full briefing for ONE named legal hold: status, start/end/reminder/issued dates, matter and workspace, admin, issuer, total custodian count, every role assigned to the hold with its View or Edit permission, and any custom fields configured for the hold (under customFields). Use this when the user asks things like: "tell me about the Smith hold", "details of hold X", "what's the status/dates of hold X", "who has access to this hold and what can they do", "what roles/permissions are on hold X", "verify the settings of hold X". Pass the exact hold name from get_legalhold_list. Pick a different tool when: the user wants the LIST of holds (use get_legalhold_list), the custodians/people on the hold (use get_legalhold_custodians), or preservation progress (use get_legalhold_preservation_collections). RESPONSE PRESENTATION — how to show this result to the user: • The result is JSON for YOU to read; do NOT paste or display the raw JSON to the user. • Present results as a concise Markdown table/summary. • Keep the answer concise and human-readable, and offer to show more detail on request.
get_legalhold_details
Lists all legal holds in the connected Casepoint organization. A legal hold (a.k.a. hold, litigation hold, preservation notice, retention notice, "hold notice") is an instruction to preserve data for a matter. Returns each hold's name, matter name/number, description, status, custodian counts by notification state, start/end/issued dates, admin, issuer, and workspace. HOLD STATUS: Valid values are 'Active' ,'Inactive' and 'Draft'. The custodian count fields (AddedCustodians, SentCustodians, AcceptedCustodians, RejectedCustodians, ReleasedCustodians, SilentCustodians) reflect hold-notification state only — they say nothing about whether data is being preserved. Use this when the user asks things like: "what holds do we have", "show me our legal holds", "list litigation holds", "any active holds", "do we have a hold on matter X". This is usually the STARTING POINT — it returns hold names you then pass to the detail, roster, or preservation tools. PAGINATION RULES — follow strictly: • Sequential only. Start with navigate='first'. To move forward, call again with navigate='next' and current_page set to the 'page' value from the previous response; navigate='previous' goes back one step. You can move only ONE step at a time and CANNOT jump to an arbitrary page. • If the user asks for a specific page ("give me page 3", "go to page 5", "show page -1"), do NOT attempt it. Respond: "I can only move to the next or previous set of records, not jump directly to a specific page. Would you like me to continue with the next set?" • NEVER expose page structure to the user — no page numbers, no "page 1 of 3", no "more pages", no total page/record counts. The 'page' value is for your internal use as current_page only. • If hasMore=true, end with a simple offer and nothing more: "Would you like me to show the next set of records?" If hasMore=false, tell the user this is the end of the list and do NOT offer a next set. • Never pass a raw user-supplied page number into this tool. Note: takes no hold id (none are exposed); other tools are driven by the hold NAME returned here. For one hold's full settings use get_legalhold_details; for its people use get_legalhold_custodians. RESPONSE PRESENTATION — how to show this result to the user: • The result is JSON for YOU to read; do NOT paste or display the raw JSON to the user. • Present results as a concise Markdown table/summary. • Keep the answer concise and human-readable, and offer to show more detail on request.
get_legalhold_list
Preservation & collection activity under ONE named legal hold — one row per custodian per data source. Shows custodian name/email, cloud type, media type/label, overall and per-source preservation status (mail / drive or sites / chat / SharePoint), collection status, authorization status, preservation & collection dates and locations, collection size, workspace, descriptions, employment status, and any custom fields configured for the data source (under customFields). This is "what data is actually being held / collected" for the hold. KEY DISTINCTION — two separate status fields in each row: • PreservationStatus — whether the custodian's DATA is being preserved (NotStarted / InProgress / Preserved / Failed / Released / Ignored). This answers "is their data actually on hold in the cloud system?" • HoldStatus — the custodian's hold-NOTIFICATION status (added / sent / accepted / rejected / released / silent). This answers "were they notified about the hold?" A custodian can have HoldStatus='accepted' (acknowledged the notice) but PreservationStatus='NotStarted' (data not yet preserved) — these are independent. Use PreservationStatus to answer questions about data preservation progress. Use this when the user asks things like: "what's being preserved for hold X", "preservation status for X", "collection progress / status", "has custodian Y's data been collected", "what sources are on hold for X", "how much has been collected". Pass the exact hold name from get_legalhold_list. PAGINATION RULES — follow strictly: • Sequential only. Start with navigate='first'. To move forward, call again with navigate='next' and current_page set to the 'page' value from the previous response; navigate='previous' goes back one step. You can move only ONE step at a time and CANNOT jump to an arbitrary page. • If the user asks for a specific page ("give me page 3", "go to page 5", "show page -1"), do NOT attempt it. Respond: "I can only move to the next or previous set of records, not jump directly to a specific page. Would you like me to continue with the next set?" • NEVER expose page structure to the user — no page numbers, no "page 1 of 3", no "more pages", no total page/record counts. The 'page' value is for your internal use as current_page only. • If hasMore=true, end with a simple offer and nothing more: "Would you like me to show the next set of records?" If hasMore=false, tell the user this is the end of the list and do NOT offer a next set. • Never pass a raw user-supplied page number into this tool. Pick a different tool when the user wants the people and their notification status rather than data sources (use get_legalhold_custodians). RESPONSE PRESENTATION — how to show this result to the user: • The result is JSON for YOU to read; do NOT paste or display the raw JSON to the user. • Present results as a concise Markdown table/summary. • Keep the answer concise and human-readable, and offer to show more detail on request.
get_legalhold_preservation_collections
The organization-wide custodian directory — every person/contact tracked in the connected Casepoint org, NOT tied to any legal hold. Each record has name, email, job title, address, country/state/city/zip, group, department, manager email, and employment status. Custodian = a person whose data may be preserved (employee, witness, contact). Use this when the user asks things like: "who are our custodians", "list all custodians", "find the custodian with email X", "give me a contact list", "who do we track / who's an employee here", "look up person Y". All filter parameters are optional partial-match (contains) filters and combine with AND; omit them to list everyone. PAGINATION RULES — follow strictly: • Sequential only. Start with navigate='first'. To move forward, call again with navigate='next' and current_page set to the 'page' value from the previous response; navigate='previous' goes back one step. You can move only ONE step at a time and CANNOT jump to an arbitrary page. • If the user asks for a specific page ("give me page 3", "go to page 5", "show page -1"), do NOT attempt it. Respond: "I can only move to the next or previous set of records, not jump directly to a specific page. Would you like me to continue with the next set?" • NEVER expose page structure to the user — no page numbers, no "page 1 of 3", no "more pages", no total page/record counts. The 'page' value is for your internal use as current_page only. • If hasMore=true, end with a simple offer and nothing more: "Would you like me to show the next set of records?" If hasMore=false, tell the user this is the end of the list and do NOT offer a next set. • Never pass a raw user-supplied page number into this tool. Pick a different tool when the question is about a SPECIFIC hold: for the people on one hold and their notification status use get_legalhold_custodians; this tool is the whole org directory. RESPONSE PRESENTATION — how to show this result to the user: • The result is JSON for YOU to read; do NOT paste or display the raw JSON to the user. • Present results as a concise Markdown table/summary. • Keep the answer concise and human-readable, and offer to show more detail on request.
get_people
Processing exceptions report for the connected eDiscovery workspace, aggregated to the data-store level. Returns the total number of data stores, the grand total exception count across the workspace, and — per data store — the individual exception category counts (password-protected files, system files, virus-infected files, unsupported attachments, unsupported loose documents, corrupted files, exceptions files, unstable mailbox) plus the data-store total. Where a data store spans multiple datasets, all per-dataset counts are summed into a single row for that data store. Use this when the user asks things like: "how many exceptions are there", "processing exceptions report", "how many password-protected or corrupted files were found", "exception breakdown by data store", "what files failed processing", "unsupported or virus-infected document counts", "unstable mailbox count". Takes no parameters — it reports on the connected workspace.
get_processing_and_exceptions_report
Production QC and exports for the connected eDiscovery workspace — the completed productions / export sets. Returns totals (number of production sets, documents produced, total volume in GB) and, per set, the data store, dataset, production set name, format, produced date, document count, volume, and Bates range (first…last Bates). Reports across ALL data stores the caller can access, and can optionally filter production sets by created date range. Use this when the user asks things like: "what have we produced", "production QC", "production volumes", "how many documents were produced", "Bates ranges", "list our productions / export sets". All parameters are optional — defaults give the full, unfiltered report across every data store. IMPORTANT: if the user specifies a date range (e.g. "between 2026-01-01 and 2026-07-28", "produced this year", "since last month"), you MUST convert it to ISO 8601 and pass it via dateRangeStart/dateRangeEnd — do not omit them just because they are optional parameters. Only omit them when the user has not given any date bound at all.
get_production_qc_and_exports
OUTPUT FORMAT — READ FIRST ══════════════════════════ Present results as a concise Markdown table/summary; never paste raw JSON to the user. Keep field labels human-readable; render null values, empty arrays, and zero counts as "—" / "None" as appropriate. Render correspondence_log and documents as their own Markdown tables under short headings. Never use a bare symbol as a label; spell every label out in full. Use exactly these labels per field: tracking_number → "Tracking Number" (NEVER "Tracking #" or "#") request_text → "Request Text" requester_name → "Requester" requester_email → "Requester Email" requester_type → "Requester Type" received_date → "Received Date" perfected_date → "Perfected Date" adjusted_due_date → "Adjusted Due Date" days_remaining → "Days Remaining" status → "Status" processing_track → "Processing Track" assigned_officer → "Assigned Officer" component → "Component" disposition_type → "Disposition Type" correspondence_log table (heading "Correspondence Log"): date → "Correspondence Date" type → "Correspondence Type" subject → "Subject" description → "Description" delivery_status → "Delivery Status" documents table (heading "Documents"): document_id → "Document ID" (NEVER "Doc #" or "#") name → "Document Name" delivery_status → "Delivery Status" Fetch the full record for a SINGLE FOIA request by its tracking number, including the correspondence log and the list of associated documents. Use this when the user asks for "tell me about request X", "show me FOIA-2026-00123", "what's the status of <tracking-number>", or any prompt that names a specific tracking number. For LIST queries across many requests, use search_requests instead. For aggregate FY metrics, use get_annual_report. Input: the tracking number string (case-insensitive; whitespace trimmed). Fields returned (render as Markdown, not raw JSON): Top-level: tracking_number, request_text, requester_name, requester_email, requester_type, received_date, perfected_date, adjusted_due_date, days_remaining, status, processing_track, assigned_officer, component, disposition_type. correspondence_log entries: date, type, subject, description, delivery_status. documents entries: document_id, name, delivery_status. Notes on specific fields: • description (correspondence_log entries) — one-line plain-text version of the correspondence body (HTML stripped and whitespace normalized server-side). • document_id (documents entries) — the released-document production package identifier. • delivery_status (documents entries) — human-readable label like "Delivery Pending", "Delivered to Portal", "Emailed (Confirmation Pending)", "Delivered by Email", "Mailed (Confirmation Pending)", "Delivered by Mail". • disposition_type is a REQUEST-LEVEL field — it is NOT repeated on each document. ERROR RESPONSES ═══════════════ When the lookup cannot return a record (blank tracking number, no matching request, backend timeout, etc.), the tool surfaces a single message. Present that message to the user as plain text (do not wrap it in a JSON block). Do NOT retry the same tracking number.
get_request_detail
Review batch and QC status snapshot for the connected eDiscovery workspace. Returns the number of review phases, the total and reviewed document counts, the total review batches, and the batch pipeline by state — pending (not started), active (in progress / accepted), and completed. Use this when the user asks about review/QC progress, batch or QC status, how many phases or batches exist, or how far along review is. Takes no parameters — it reports on the connected workspace.
get_review_batch_qc_status
Review team productivity report for the connected eDiscovery workspace, grouped by reviewer. Returns one row per reviewer with documents reviewed, image counts and edits summed across the date range, total review time (HH:MM:SS), and the hourly review rate (total documents reviewed per review-hour). Use this when the user asks things like: "how productive is the review team", "reviewer productivity", "review rate / docs per hour", "who reviewed the most documents", "how much time did reviewers spend". All parameters are optional — defaults give the full, unfiltered report for every reviewer.
get_review_team_productivity
Orientation snapshot of the connected eDiscovery workspace (matter). Returns these workspace-level fields: workspaceName, workspaceStatus (Active / Closed / Archived), matterType, openDate, and totalCustodians. Document counts cover EVERY datastore the caller can access (not just the default one) and are returned in two parts: - 'aggregate' — the default overview: accessibleDataStores (how many datastores the caller can access) plus totalDocuments and producedDocuments summed across all of them. - 'dataStores' — an array with one entry per datastore, each carrying dataStoreId, dataStoreName, totalDocuments and producedDocuments. Workspace name/status/matter type and custodian count are workspace-level (not per datastore). By DEFAULT present the 'aggregate' overview. Only break the numbers down per datastore (from 'dataStores') when the user explicitly asks for individual / per-datastore data — e.g. "documents per datastore", "breakdown by datastore", "counts for each datastore". Use this when the user asks things like: "what is this matter / workspace", "give me an overview", "matter type / status / open date", "how many documents are in here", "how many custodians", "documents per datastore". Takes no parameters — it reports on the connected workspace.
get_workspace_summary
OUTPUT FORMAT — READ FIRST ══════════════════════════ Present results as a concise Markdown table/summary; never paste raw JSON to the user. Use fully spelled-out, human-readable column headers — never a bare symbol. Every DATE field's header MUST include the word "Date". Use exactly these headers per field: tracking_number → "Tracking Number" (NEVER "Tracking #" or "#") request_type → "Request Type" requester_name → "Requester" received_date → "Received Date" perfected_date → "Perfected Date" adjusted_due_date → "Adjusted Due Date" state → "State" status → "Status" processing_track → "Processing Track" component → "Component" days_remaining → "Days Remaining" closed_by → "Closed By" closed_date → "Close Date" close_remark → "Close Remarks" deliver_mode → "Delivery Mode" estimated_completion_date → "Estimated Completion Date" RENDER EVERY FIELD RETURNED — DO NOT CHERRY-PICK COLUMNS ════════════════════════════════════════════════════════ The row shape is fixed — every row the tool returns contains ALL 16 fields listed above, in that order. Your default rendering MUST include EVERY one of those fields as its own Markdown-table column, using the headers exactly as mapped. Do NOT drop columns just because the values look uninteresting for a specific query (e.g. don't omit "Request Type", "Perfected Date", "Adjusted Due Date", "State", "Status", "Processing Track", "Days Remaining", "Close Remarks", or "Estimated Completion Date" merely because the user's prompt was about closures). Rules: • The column count in the header row equals 16 (one per field above). Same count on the delimiter row. Same count on every data row. • Render null / empty values as "—" (em dash). Never collapse a column just because every row has a null value. • Do NOT reorder columns. The order above is the required order. • The ONLY exception is when the user's prompt explicitly narrows the columns ("show only tracking number and close date", "just requester and status") — in that case render exactly the requested subset in the requested order. • If the table is wide, that's fine — do not truncate, wrap by omitting columns, or promote fields into prose narration. PURPOSE ═══════ Search FOIA Requests using natural-language-derived filter clauses. READ-ONLY. Scoped to the caller's connected organization + role visibility. HOW FIELDS ARE ADDRESSED ════════════════════════ Every field is referenced by its human DISPLAY LABEL (e.g. "Due Date", "Status", "Component"). There are no internal identifiers in this contract — `fieldname` is always a display label, both in your input and in any warning echoed back. Use the standard labels in the trigger table below. Never invent or guess a label, and never ask for or expect a field list — the available fields are exactly the standard labels. WHEN TO USE ═══════════ Prompt asks for a LIST of requests filtered, sorted, or counted. WHEN NOT TO USE ═══════════════ - Single-request detail (correspondence log, all custom fields) — out of scope. - Aggregate metrics (FY report, fee-waiver totals, avg processing days) — out of scope. - Mutations (create / update / close a request) — this tool is read-only. - Cross-organization queries — scoped to the caller's connected organization only. TRIGGER TABLE — apply ALL matching rows (use these labels exactly as written) ═════════════════════════════════════════════════════════════════════════════ REQUEST-TYPE FILTERING (add a "Request Type" clause in cases 1–2; ALWAYS combine it with any OTHER filters the prompt also gives): 1. The prompt names a request TYPE as a descriptor of the requests — "FOIA requests", "appeals", "consultation requests", "Privacy Act requests". This holds even when other filters are present, and you then send BOTH clauses: • "in-progress FOIA requests" → "State" Equal "In Progress" AND "Request Type" Equal "FOIA" • "overdue Appeal requests" → "Due Date" LessThan <today> AND "Request Type" Equal "Appeal" 2. Bare "give me all requests" / "list requests" with NO other filter → "Request Type" Equal "FOIA" (a clause is required; "all requests" defaults to the FOIA type). Do NOT add a "Request Type" clause when: - "FOIA" only names the APPLICATION / system — "requests in the FOIA application", "in-progress requests in FOIA" — that is the app, not the type; send only the real filters so all types return. - the prompt gives a filter (State, Status, Date, Requester, etc.) and names NO type at all — "in-progress requests", "overdue requests" — send only those clauses. Litigation is excluded server-side and is never available, so never filter by it. | Prompt trigger | Clause (field label · operator · value) | |-----------------------------------------|------------------------------------------| | A type describes the requests: "FOIA | "Request Type" Equal "<TypeName>" | | requests" / "appeals" / "Privacy Act | (ALSO add the other clauses, e.g. | | requests" (even with other filters) | State, when both are named) | | Bare "all requests" with NO other filter| "Request Type" Equal "FOIA" | | Any other filter given, no type named | (no Request Type clause — all types) | | "open" / "still open" / "not closed" | "State" NotEqual "Closed" | | WITHOUT "status" (request is in any | ("open" ≡ NOT Closed — i.e. any of | | state other than Closed) | In Progress / On Hold / Perfected) | | "in progress" WITHOUT "status" | "State" Equal "In Progress" | | (or "... state") | | | "closed" / "perfected" / "on hold" | "State" Equal "<word>" | | WITHOUT "status" (or "... state") | | | the user says the word "status": | "Status" Equal "<value>" | | "<value> status" (interim sub-status) | | | "overdue" / "past due" | "Due Date" LessThan <today ISO> | | "due today" | "Due Date" Equal <today ISO> | | "due in N days" | "Due Date" GreaterThanOrEqual today | | | AND LessThanOrEqual today+N | | "filed by X" / "requester X" | "Requester" Equal "<X name OR email>" | | "assigned to X" / "owned by X" | "Assigned To" Equal "<X name OR email>" | | "closed by X" | "Closed By" Equal "<X name OR email>" | | "closed on X" / "close date X" | "Close Date" Equal <ISO date> | | "closed after X" / "closed since X" | "Close Date" GreaterThanOrEqual <ISO> | | "closed before X" | "Close Date" LessThan <ISO> | | "close remark(s) contain X" / | "Close Remarks" Contains "<X>" | | "closing note mentions X" | (label is PLURAL: "Close Remarks") | | "delivered by mail" / "delivery via X" | "Delivery Mode" Equal "<X>" | | "estimated to complete by X" / | "Estimated Completion Date" | | "target completion date X" | LessThanOrEqual <ISO> | | "in <C> component" / "<C> component" | "Component" Equal "<C>" | The labels above ("Request Type", "State", "Status", "Due Date", "Requester", "Assigned To", "Closed By", "Close Date", "Close Remarks", "Delivery Mode", "Estimated Completion Date", "Component") are the standard FOIA labels — use them EXACTLY as written; they must match the organization's search-profile alias (e.g. "Close Remarks" is PLURAL). If a clause comes back dropped with reason "unknown fieldname", the label you sent didn't match a searchable field — either the search profile doesn't project it, OR the label is spelled differently than the catalog's (check singular/plural and exact wording). If that droppedClauses entry includes a "didYouMean" value, silently re-issue the SAME search ONCE with that exact label instead; otherwise tell the user the filter couldn't be applied. STATE vs STATUS — two distinct fields; route by the WORD the user uses: - NO "status" word (or the user says "... state") → "State" (the request status). Values: "In Progress", "Closed", "On Hold", "Perfected". "open" / "still open" means NOT Closed → "State" NotEqual "Closed" (it is NOT a synonym for "In Progress"). • "open requests" / "still open" → "State" NotEqual "Closed" • "requests that are in progress" → "State" Equal "In Progress" • "requests in progress state" → "State" Equal "In Progress" - The user says the word "status" → "Status" (the finer interim / sub-status). Pass the plain value; the server matches the interim status by exact name and searches EVERY interim id sharing that name (OR'd) — do NOT guess or expand ids yourself. • "requests in progress status" → "Status" Equal "In Progress" • "FOIA requests in progress status"→ "Status" Equal "In Progress" AND "Request Type" Equal "FOIA" - If the user says "<X> status" but no interim status named X exists, the search returns a no-match warning; it does NOT fall back to "State". In responses these map to the row fields `state` (request status) and `status` (interim). DO NOT ══════ - Add a "Request Type" clause when "FOIA" only names the FOIA application, or when the user gave another filter (Status, Date, etc.) but named no type — omit it so all types return. (Exception: a bare "all requests" with NO other filter → "Request Type" Equal "FOIA".) - Invent or guess field labels — use only the standard labels in the trigger table. - Use Between/In/NotIn — not supported in v1; use OR-chained Equal clauses. - Sort by anything other than a supported sort key (see sortBy below) — unknown keys silently fall back to "tracking_number" with warnings.adjustedSort set. - Loop the same payload after an error envelope — recompose, don't retry as-is. INPUT (stringified JSON) ════════════════════════ { "where": [{ "fieldname":"<display label>","operator":"<op>","value":"<display value>","operand":"And"|"Or" }, ...], "sortBy":"<sort key>","sortOrder":"asc"|"desc", "currentPage": <int >= 1> } Operators: Equal, NotEqual, Contains, StartsWith, EndsWith, LessThan, LessThanOrEqual, GreaterThan, GreaterThanOrEqual, IsNull, IsNotNull. sortBy: one of tracking_number, received_date, perfected_date, adjusted_due_date, closed_date, estimated_completion_date (default: tracking_number). Anything else falls back to tracking_number. closed_date is only meaningful when the population is restricted to closed requests (State Equal "Closed"); rows without a close date sort last. Limits: max 50 clauses per payload; max 256 chars per value. Values: for a choice/lookup field, pass the option's display name as value. For people fields (Requester / Assigned To / Closed By), a name or email also works — the resolver matches "<name> (<email>)" rows by name alone, email alone, or full string. Dates: ISO-8601 (yyyy-MM-dd). "today" resolves to the current server-UTC date. Pagination: `currentPage` is optional (default 1). Page size is fixed by server configuration and is NOT a caller parameter. "more" / "next page" → re-call with currentPage + 1. Empty payload ("" / "{}" / {"where":[]}) is rejected with NO_CLAUSES — there is no field-listing mode; always send at least one clause. OUTPUT ══════ { items: [<row>, ...], warnings: { droppedClauses: [{ fieldname, operator, reason }], unresolvedClauses: [{ fieldname, value, reason }], ambiguousResolution: [{ fieldname, value, matchedCount, pickedValue }], adjustedSort: <sort key | null> }, pagination: { totalCount, currentPage, recordPerPage, totalPages, hasMore, outOfRange }, message: <string | null> } row = { tracking_number, request_type, requester_name, received_date, perfected_date, adjusted_due_date, state, status, processing_track, component, days_remaining, closed_by, closed_date, close_remark, deliver_mode, estimated_completion_date } state = the request status (e.g. "In Progress", "Closed", "On Hold", "Perfected"). status = the interim status — a finer-grained sub-status within the current state; may be null when no interim status is set. closed_by = user (name / email) who closed the request; null while the request is still open. closed_date = ISO date the request moved to Closed state; null when the request is still open. close_remark = free-text closing remark captured at close time; null when the closer left it blank. deliver_mode = delivery-method label used to send the response to the requester (e.g. "Email", "Portal", "Mail"). Null when no delivery has been logged yet. estimated_completion_date = ISO date the assigned officer projected as the completion target for open work; null when no estimate is set. This is a planning field — do NOT conflate with adjusted_due_date (the statutory / extended deadline). When listing/grouping/counting BY TYPE, group on request_type — never on the tracking-number prefix (prefixes are not a type signal and misclassify rows). (`fieldname` in warnings is the same display label you sent.) Notes: - warnings is present ONLY when at least one warning exists; when there are none the whole warnings object is omitted from the response (do not expect an empty warnings block). - pagination.recordPerPage in the OUTPUT reflects the server-configured page size. - pagination.totalCount is rows on THIS page (not DB total); use hasMore as the "is there more?" signal. WARNING HANDLING (informational, NOT retry signals) ════════════════════════════════════════════════════ - SUCCESS-SILENT: warnings appear ONLY when something went wrong. When the warnings object is absent, say NOTHING about filters or validation — do NOT announce that nothing was dropped/unresolved. Never surface the words "clause", "dropped", or "unresolved" to the user; when a warning does occur, describe it in plain terms. - warnings.droppedClauses non-empty → MUST tell the user which filter was dropped and why (e.g. "I couldn't filter by X because ..."). Don't silently hide it. - warnings.unresolvedClauses non-empty → the user's value didn't match any organization lookup row. Ask them to clarify the spelling. - warnings.ambiguousResolution non-empty → multiple lookup rows share the same name; the first was picked. Surface the ambiguity to the user. - warnings.adjustedSort set → an unknown sortBy was coerced to the default; surface it. ERROR ENVELOPES (each terminal — recompose, don't loop) ═══════════════════════════════════════════════════════ - INVALID_JSON → repair the payload's JSON syntax. - NO_CLAUSES → empty where[]. Add ≥1 clause. For a bare "all requests" with no other filter, use "Request Type" Equal "FOIA". If the user gave a real filter (Status, Date, etc.), send that instead and add no Request Type clause. - PAYLOAD_TOO_LARGE → where.length > 50. Consolidate (Contains instead of many Equals). - RESERVED_FIELD → "values":[] is reserved for v1.1; use OR-chained Equal in v1. - INVALID_PAGINATION → currentPage < 1. - unauthorized_context → the session has no valid tenant context. Tell user to reconnect. - all_clauses_dropped → every clause failed validation. Re-read warnings.droppedClauses; if reason is "unknown fieldname", that field isn't filterable in this organization — tell the user. Do NOT keep guessing labels. - all_clauses_unresolved → every choice-field clause missed lookup; ask user to clarify. - casepoint_api_timeout → backend slow. Narrow the search (more selective clauses). PRE-SUBMIT CHECKLIST — re-read your composed `where` BEFORE returning ═════════════════════════════════════════════════════════════════════ 1. Request Type clause? Add "Request Type" Equal "<TypeName>" if (a) a type describes the requests ("FOIA requests", "appeals", "Privacy Act requests") — KEEP it even when the prompt also names a State/Date/etc.; add both clauses (e.g. "in-progress FOIA requests" → State AND Request Type), or (b) it is a bare "all requests" with NO other filter → Equal "FOIA". Do NOT add it if the prompt gave a filter and named no type, or "FOIA" only names the application — then all types return. 2. Did the prompt mention status? Route by the word: - WITHOUT the word "status" (or said as "... state") → a "State" clause (NOT "Status"). "open" / "still open" → "State" NotEqual "Closed" (NOT the literal "Open", and NOT "In Progress"); "in progress" → "State" Equal "In Progress". - WITH the word "status" ("<value> status") → a "Status" clause (interim). Send the single value as-is; the server OR-expands it across all matching interim ids. 3. Did the prompt name a person ("filed by X" / "assigned to X" / "closed by X")? → correct person-field clause present? Use label "Requester" / "Assigned To" / "Closed By" respectively. If any of 1–3 are in the prompt but missing from `where`, your payload is wrong.
search_requests
How do I improve a ChatGPT Plugin's discoverability?
The levers are the listing surface agents actually read: names, descriptions, keywords, tool metadata, and registry health. Which lever matters depends on where discovery breaks, which is what continuous measurement shows.
What are Casepoint alternatives on ChatGPT?
As of 2026-08-14, Casepoint competes with Aurora, Chat Jurídico, Courtroom5, GC AI, LawVu, Quilia in ChatGPT Legal Practice & Matter Platforms, ranked by public Discoverability Score.
Where is this profile measured?
This profile uses the geography attached to the latest public registry snapshot: US. Locale tags are intentionally omitted.