A single tool and interview to centralize some tedious Docassemble admin configuration tasks.
- Install the Document Assembly Line packages (support files for Court Forms Online)
- Searchable user management - reset passwords and change privileges.
- Report on and delete stale developer accounts, including their playground files.
- Installing or updating several packages at once.
- Listing and viewing the contents of an (unencrypted) interview to facilitate debugging errors on production servers.
- View analytics/stats captured with
store_variable_snapshot. - List the files inside a particular package installed on the server.
- Gather files from a user who left the organization/unknown username and password.
- Review screen generator
- validate DOCX Jinja2 templates
- Generate a custom bootstrap theme for your interviews.
The Interview Text Linter delegates YAML structure, accessibility, translatability,
and Assembly Line style checks to DAYamlChecker.
The dashboard adds its report navigation, readability scores, and spellcheck around
those structured findings. Optional style LLM checks use DAYamlChecker's standard
OPENAI_BASE_URL, OPENAI_API_KEY, and OPENAI_MODEL configuration.
Ideas:
- Add a link to the dispatch directive for an existing file in an existing package.
- Generate translation files [TBD].
To use, you must create a docassemble API key and add it to your configuration, like this:
install packages api key: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
If you want the ALDashboard to be a dropdown option for admins and developers, add the following to the configuration before your install packages api key:
administrative interviews:
- interview: docassemble.ALDashboard:data/questions/menu.yml
title: Dashboard
required privileges:
- admin
- developer
When installed on a docassemble server, ALDashboard exposes a Flask API at:
POST /al/api/v1/dashboard/translationPOST /al/api/v1/dashboard/docx/auto-labelPOST /al/api/v1/dashboard/docx/runsPOST /al/api/v1/dashboard/docx/relabelPOST /al/api/v1/dashboard/bootstrap/compilePOST /al/api/v1/dashboard/translation/validatePOST /al/api/v1/dashboard/review-screen/draftPOST /al/api/v1/dashboard/variable-reportPOST /al/api/v1/dashboard/court-form/profilesPOST /al/api/v1/dashboard/docx/validatePOST /al/api/v1/dashboard/yaml/checkPOST /al/api/v1/dashboard/yaml/reformatPOST /al/api/v1/dashboard/pdf/label-fieldsPOST /al/api/v1/dashboard/pdf/fields/detectPOST /al/api/v1/dashboard/pdf/fields/relabelPOST /al/api/v1/dashboard/pdf/repairGET /al/api/v1/dashboard/jobs/{job_id}GET /al/api/v1/dashboard/jobs/{job_id}/downloadDELETE /al/api/v1/dashboard/jobs/{job_id}GET /al/api/v1/dashboard/openapi.jsonGET /al/api/v1/dashboard/docs
The API uses docassemble API key authentication via api_verify(). Endpoints default to synchronous execution and support mode=async (or async=true) for Celery-backed processing.
To enable async mode, add this module to your docassemble configuration:
celery modules:
- docassemble.ALDashboard.api_dashboard_worker-
POST /al/api/v1/dashboard/variable-report- Input: interview YAML via
yaml_text, upload, orplayground_project+playground_yaml_file; optionalreport_title,infer_assemblyline. - Optional
shape:intake(default),court_form,motion,affidavit,letter. See Court form shapes. - Court shapes also take
court_profileandinclude_certificate_of_service, and returndocx_base64by default. - Output:
mako_markdown, variable metrics, and for court shapesprofile_id,profile_name,styles, and asectionsmap naming the template each fixed section came from.
- Input: interview YAML via
-
POST /al/api/v1/dashboard/court-form/profiles- Input: none.
- Output: the
shapesthis server can draft, the jurisdictionprofilesinstalled on it, and thesectionsa profile may define.
-
POST /al/api/v1/dashboard/translation- Input:
interview_path, one or more target languages (tr_langs), optional GPT settings. - Output: translation XLSX metadata and optional base64 file content.
- Input:
-
POST /al/api/v1/dashboard/docx/auto-label- Input: DOCX file upload, optional
custom_people_names. - Uses
docassemble.ALToolbox.llmsfor OpenAI configuration. - Optional per-request overrides:
openai_api,openai_base_url,openai_model. - Prompt customization:
custom_prompt,additional_instructions. - Optional output budget override:
max_output_tokens. - Output:
resultsarray by default; includeinclude_labeled_docx_base64=trueto also get updated DOCX bytes.
- Input: DOCX file upload, optional
-
POST /al/api/v1/dashboard/docx/runs- Input: DOCX file upload (or base64 content).
- Output: parsed run list as
results, each entry[paragraph_index, run_index, run_text]. - Traversal includes body paragraphs, tables, headers, and footers.
-
POST /al/api/v1/dashboard/docx/relabel- Input: existing
resultsfrom first-pass label run and/or DOCX upload. - Supports index-based edits:
replace_labels_by_index,skip_label_indexes. - Supports explicit additions:
add_labels. - Supports range-based rule additions:
add_label_rules(paragraph range + match conditions). - Output: edited
resultsarray by default; includeinclude_labeled_docx_base64=trueto also get updated DOCX bytes. - In async mode, download binary file output from
GET /al/api/v1/dashboard/jobs/{job_id}/download.
- Input: existing
-
POST /al/api/v1/dashboard/bootstrap/compile- Input: SCSS upload or
scss_text. - Output: compiled CSS text or base64.
- Operational notes:
- Requires
nodeandnpmavailable on serverPATH. - First run downloads Bootstrap source into
/tmpand runsnpm install/npm run css-compile, so it may be noticeably slower. - Requires outbound HTTPS access to fetch Bootstrap and npm dependencies.
- Writes temporary build artifacts under
/tmp; ensure adequate disk space and cleanup policies.
- Requires
- Input: SCSS upload or
-
POST /al/api/v1/dashboard/translation/validate- Input: translation XLSX.
- Output: structured errors/warnings/empty rows.
-
POST /al/api/v1/dashboard/review-screen/draft -
POST /al/api/v1/dashboard/variable-report -
POST /al/api/v1/dashboard/court-form/profiles- Input: one or more YAML files.
- Output: generated review-screen YAML draft.
-
POST /al/api/v1/dashboard/docx/validate- Input: one or more DOCX templates.
- Output: per-file Jinja rendering errors.
-
POST /al/api/v1/dashboard/yaml/check- Input:
yaml_text(oryaml_content) and optionalfilename. - Output: structured DAYamlChecker issues with
errors,warnings, andvalid.
- Input:
-
POST /al/api/v1/dashboard/yaml/reformat- Input:
yaml_text(oryaml_content), optionalline_lengthandconvert_indent_4_to_2. - Output: reformatted YAML in
formatted_yamlandchangedboolean.
- Input:
-
POST /al/api/v1/dashboard/pdf/label-fields- Input: PDF upload.
- Output: PDF with fields detected and optionally relabeled (backward-compatible alias of
/pdf/fields/detect).
-
POST /al/api/v1/dashboard/pdf/fields/detect- Input: PDF upload.
- Optional flags:
relabel_with_ai,include_pdf_base64,include_parse_stats. - Optional exact-name list:
target_field_names(ordered list to apply after detection). - Output: PDF with detected fields added, plus optional AI/target-name relabeling.
-
POST /al/api/v1/dashboard/pdf/fields/relabel- Input: PDF with existing fields.
- Relabel modes:
field_name_mapping(exact old->new map), orderedtarget_field_names, or AI (relabel_with_ai=true). - Output: Relabeled PDF and resulting field names; optional parse stats/base64 output.
-
POST /al/api/v1/dashboard/pdf/repair- Run a single repair action on an uploaded PDF. Omit
actionto list available actions. actionvalues:ghostscript_reprint,qpdf_repair,restore_checkbox_appearances,unlock,repair_metadata,ocr.ghostscript_reprint: Re-distill through Ghostscript. Optionalpreserve_fields=trueto extract and re-apply field locations.qpdf_repair: Fix cross-reference tables and rebuild the page tree via pikepdf.restore_checkbox_appearances: Add missing checkbox appearance streams without changing text field appearances.unlock: Remove encryption/permissions. Optionalpasswordparameter.repair_metadata: Fix broken catalog/metadata entries (pikepdf, then pdfrw fallback).ocr: Add searchable text layer via ocrmypdf. Optionallanguage(defaulteng) andskip_text(defaulttrue).- Output:
repair_resultobject and optionalpdf_base64.
- Run a single repair action on an uploaded PDF. Omit
-
GET /al/api/v1/dashboard/jobs/{job_id}/download- Streams the first available file artifact from a completed async job.
- Optional query parameters:
index(0-based artifact index)field(exact artifact field path from JSON result)
Live docs:
GET /al/api/v1/dashboard/openapi.jsonGET /al/api/v1/dashboard/docs
The Interview Intake Document Generator can arrange an interview's variables into a draft court filing rather than a list of fields. The interview's screens become the middle of the document; a jurisdiction profile supplies the parts the court fixes.
Shapes:
| Shape | What it drafts |
|---|---|
intake |
The original field-and-value summary. Still the default. |
court_form |
Caption, title, the interview's screens as numbered sections, signature block. |
motion |
The same, wrapped in a "NOW COMES" introduction and a prayer for relief, with a certificate of service. |
affidavit |
The same, introduced as sworn statements and closed with the jurisdiction's perjury language and a jurat. |
letter |
No caption: sender, date, recipient, RE: line, body, closing. |
Profiles shipped with the package, each modeled on that court's real forms:
ma_trial_court, il_circuit, vt_superior, mi_scao, mn_district,
dmass_federal, and a neutral generic.
Nothing about a court's layout is compiled into Python.
- Profiles are YAML in
docassemble/ALDashboard/data/sources/court_form_profiles/. Each defines the caption, running header and footer, signature block, certificate of service and jurat as ordered blocks, plus the Word styles the document should use. Addingnh_circuit.ymladds annh_circuitprofile to the dropdown with no code change. A profile canextends:another so a new court only states what differs. - Word-authored overrides go in
docassemble/ALDashboard/data/templates/court_forms/<profile id>/<section>.docx. A fragment replaces just that section and is copied in verbatim; the rest of the form still comes from the profile. Use this when a caption is easier to draw in Word than to describe. - Fonts and spacing are Word styles. Everything the generator writes is
tagged
CourtBodyText,CourtCaptionHeading,CourtDocumentTitleand so on, so a court that wants Arial instead of Times is a one-line edit to the profile rather than a sweep through the layout.
Servers that would rather not fork the package can point the
court form profiles configuration key at their own directory of profiles.
Both README files under those directories document the block and placeholder syntax in full.
from docassemble.ALDashboard.variable_report_generator import generate_variable_report
result = generate_variable_report(
[yaml_text],
report_title="Motion to Vacate Default Judgment",
shape="motion",
court_profile="ma_trial_court",
output_docx_path="/tmp/motion.docx",
)
result["sections"] # {'caption': 'yaml', 'signature': 'yaml', ...}This is the entry point the ALWeaver's variable_report.py already calls, so
the Weaver reaches the court shapes by passing shape and court_profile
through. docassemble.ALDashboard.court_form_generator.generate_court_form_docx
is available directly when a caller has already extracted the interview's
groups and variables.
ALDashboard also exposes a lightweight MCP-style discovery layer over HTTP:
POST /al/api/v1/mcp(JSON-RPC 2.0 endpoint)GET /al/api/v1/mcp(endpoint metadata)GET /al/api/v1/mcp/tools(convenience tool listing)GET /al/api/v1/mcp/docs(human-readable docs)
Supported JSON-RPC methods:
initializepingtools/listtools/call
tools/list discovers tools generated from:
- ALDashboard REST OpenAPI paths (
/al/api/v1/dashboard/...) - ALWeaver REST paths (
/al/api/v1/weaver...) only whendocassemble.ALWeaveris installed.
For development-only fallback discovery from a local checkout, set:
export ALDASHBOARD_MCP_DEV_MODE=true
export ALWEAVER_REPO_PATH=~/docassemble-ALWeaverExample:
curl -X POST "https://YOURSERVER/al/api/v1/mcp" \
-H "Content-Type: application/json" \
-H "X-API-Key: YOUR_API_KEY" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'Tool execution example:
curl -X POST "https://YOURSERVER/al/api/v1/mcp" \
-H "Content-Type: application/json" \
-H "X-API-Key: YOUR_API_KEY" \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"aldashboard.get_al_api_v1_dashboard_openapi_json","arguments":{}}}'tools/call securely reuses the same authenticated request context (for example X-API-Key or Authorization) and does not require storing a separate API key in MCP configuration.
Purpose of each mode:
POST /docx/runs: inspection mode- Returns
[paragraph_index, run_index, run_text]. - Use this to understand document coordinates before deterministic edits.
- Returns
POST /docx/auto-label: draft generation mode- Generates initial label suggestions (
results).
- Generates initial label suggestions (
POST /docx/relabel: editing/apply mode- Edits draft labels (
replace_labels_by_index,skip_label_indexes,add_labels,add_label_rules). - If DOCX content is provided and
include_labeled_docx_base64=true, returns an updated DOCX.
- Edits draft labels (
GET /jobs/{job_id}/download: async file download mode- Streams final binary output from completed async jobs.
Full workflow: upload DOCX -> draft labels -> manual edits (change, delete, add) -> download final DOCX
Step 1. Create draft labels (async)
curl -X POST "https://YOURSERVER/al/api/v1/dashboard/docx/auto-label" \
-H "X-API-Key: YOUR_API_KEY" \
-F "mode=async" \
-F "file=@/path/to/input.docx" \
-F "openai_base_url=https://YOURRESOURCE.openai.azure.com/openai/v1/" \
-F "openai_api=YOUR_AZURE_OPENAI_KEY" \
-F "openai_model=gpt-5-mini"Step 2. Poll job until status=succeeded, then read data.results
curl -H "X-API-Key: YOUR_API_KEY" \
"https://YOURSERVER/al/api/v1/dashboard/jobs/JOB_ID_FROM_STEP_1"Step 3. Edit labels manually (change one, delete one, add one) and request final DOCX (async)
curl -X POST "https://YOURSERVER/al/api/v1/dashboard/docx/relabel" \
-H "Content-Type: application/json" \
-H "X-API-Key: YOUR_API_KEY" \
-d '{
"mode": "async",
"filename": "input.docx",
"file_content_base64": "BASE64_DOCX_HERE",
"results": [[1,0,"{{ letter_date }}",0],[2,0,"{{ old_name }}",0],[3,0,"{{ keep_me }}",0]],
"replace_labels_by_index": {"0":"{{ edited_letter_date }}"},
"skip_label_indexes": [1],
"add_labels": [[0,0,"{{ added_new_label }}",0]],
"include_labeled_docx_base64": true
}'Step 4. Poll relabel job, then download final DOCX
curl -H "X-API-Key: YOUR_API_KEY" \
"https://YOURSERVER/al/api/v1/dashboard/jobs/JOB_ID_FROM_STEP_3"
curl -L -o final_labeled.docx \
-H "X-API-Key: YOUR_API_KEY" \
"https://YOURSERVER/al/api/v1/dashboard/jobs/JOB_ID_FROM_STEP_3/download"View / search sessions by user and interview name







