Skip to content

Jasper Report Services API

Base path: /jasper-report-services

The supported integration surface is the registry, discovery, report metadata/assets, and report execution endpoints below. Browser management pages and form-backed action handlers are documented separately because they are implementation-facing UI contracts, not a stable public integration API.

Authentication uses the Central acugis_session cookie only. See authentication.md. JSON error bodies generally contain error; execution and image errors are often plain text or are passed through from the Jasper engine.

Supported integration endpoints

Report registry

GET /api/reports returns all on-disk *.report.json definitions as:

[
  {"name":"sales-summary","title":"Sales Summary","datasource":"ReportingDB"}
]

name is the _repName report key, title falls back to name, and datasource may be empty. There is no auth, ACL filtering, database dependency, or method gate: PHP returns the same representation for other HTTP methods too. Integrations should use GET.

Datasource registry

GET /api/datasources returns enabled datasource names:

[{"name":"ReportingDB"}]

There is no auth or method gate. If the application DB is unavailable or neither supported datasource table exists, the endpoint returns 200 []; it does not emit a database error. Integrations should use GET.

Discovery

GET /api/discovery (or /api/discovery/index.php) requires a valid session when auth is enabled. It syncs report definitions into Central, filters by report view permission, and returns:

{
  "service":"jasper-report-service",
  "resource_type":"jasper_report",
  "items":[{
    "id":"sales-summary",
    "resource_type":"jasper_report",
    "resource_key":"sales-summary",
    "title":"Sales Summary",
    "description":"Jasper report",
    "url":"/jasper-report-services/reports/view.php?report=sales-summary&datasource=ReportingDB",
    "category":"Reports",
    "service":"jasper-report-service",
    "thumbnail":"/jasper-report-services/reports/report_thumbnail.php?report=sales-summary"
  }]
}

thumbnail is omitted when no PNG exists. Typical failures are 401, 403, or 503 authentication JSON errors.

Resource sync

GET /api/resource-sync returns a platform-admin-only capability response:

{"ok":true,"service":"jasper-report-service","hint":"POST to run a full Jasper report resource sync (idempotent)."}

POST /api/resource-sync performs the idempotent sync and returns:

{
  "service":"jasper-report-service",
  "ok":true,
  "registered":1,
  "already_exists":2,
  "errors":0,
  "skipped":false
}

New resources receive default permissions for Administrators:admin, Editors:edit, and Public:view when those groups exist. Existing permissions are not replaced. Methods other than GET/POST return 405, Allow: GET, POST, and {"error":"method not allowed"}. A missing/unreachable sync DB returns 503 with ok:false, service, and a configuration error string.

Expanded report configuration

GET /reports/get_report_config.php?report={report} returns the definition and expands source: "sql:..." parameter options against the configured datasource. The report key is normalized to lowercase and may contain only a-z, digits, _, and -.

{
  "name":"Sales Summary",
  "report":"sales-summary",
  "datasource":"ReportingDB",
  "format":"html",
  "parameters":[{
    "name":"region",
    "type":"select",
    "label":"Region",
    "required":false,
    "hidden":false,
    "options":[{"label":"North","value":"N"}]
  }],
  "access_groups":"Public"
}

The definition format is file-backed and can contain additional fields. parameters may also be named params on disk but is normalized to parameters when SQL options are expanded. Responses: 400 {"error":"invalid report"}, 404 {"error":"report not found"}, 403 {"error":"Permission denied"}, or 503 when Central is configured but unavailable.

Raw report definition

GET /reports/serve_report_definition.php?report={report} returns the unexpanded JSON file verbatim with X-Content-Type-Options: nosniff. Direct web access to reports/json/ is denied. Responses are 400 text/plain (Invalid report.), empty 404, report ACL 403, or Central 503.

Thumbnail

GET /reports/report_thumbnail.php?report={report} returns the stored asset as image/png with Cache-Control: private, max-age=3600. Publishing accepts PNG/JPEG/WebP uploads but the service stores all assets under a .png name and always declares image/png; clients should therefore rely on the declared contract only for correctly published PNGs. Invalid, missing, and absent assets all produce an empty 404; ACL and Central errors follow runtime authorization behavior.

Execute a report

GET /reports/execute_report.php validates the report and proxies the request query string to the internal Jasper engine.

Reserved query parameters:

  • _repName — required report key.
  • _repFormat — optional; defaults to html. Accepted values are html, pdf, xlsx, xls, csv, docx, rtf, odt, ods, pptx, and xml.
  • _dataSource — required by the internal engine even though the PHP proxy does not prevalidate it. Use the definition's datasource.
  • _outFilename — optional engine output filename.
  • Any non-underscore query key is passed as a Jasper parameter. Repeat a key for multi-value parameters. The engine excludes SUBREPORT_DIR and REPORT_DIR.

Success is a streamed report representation. The proxy forwards the engine's status plus Content-Type, Content-Disposition, Cache-Control, Pragma, and Expires. HTML chart image URLs are rewritten to the authenticated image proxy.

Proxy-generated errors:

  • 400 text/plain: Invalid report. or Unsupported export format.
  • 404 text/plain: Report not found.
  • 403: report ACL denial.
  • 503 text/plain: Jasper engine URL is not configured.
  • 502 text/plain: Jasper proxy error...

Engine errors pass through, commonly as JSON with error, or with exceptionClass and exceptionMessage. The PHP script reads _repName from $_REQUEST, but forwards only QUERY_STRING; POST body parameters therefore do not form a usable execution request. Use GET.

Report image proxy

GET /report_image.php?_repName={report}&image={image}&uuid={run} proxies an image generated during HTML execution. _repName (or alias report) is required for ACL enforcement; all other query values are passed through. This endpoint requires login plus report view, so anonymous Public report HTML may load while its generated images do not. Invalid report produces empty 403; missing engine URL produces empty 503; proxy failure produces empty 502. Successful content type and length come from the engine.

Debug JSON endpoints

GET /debug/session.php is a read-only, gated session probe described in authentication.md. Its successful schema contains:

{
  "service":"jasper-report-service",
  "auth_enabled":true,
  "cookie_name":"acugis_session",
  "cookie_present":true,
  "token_len":43,
  "central_db":"ok",
  "search_path":[],
  "session_lookup_ok":true,
  "authenticated":true,
  "user":{"id":1,"username":"operator","email":"","is_admin":false},
  "groups":["Public"]
}

GET /debug/param_pipeline_php.php is an unauthenticated development echo endpoint. It returns raw_query_string, $_GET, $_REQUEST, and parse_str($rawQs). Do not expose it publicly or treat it as a supported integration API.

UI-only routes

These return HTML, redirects, or server-side effects and are not supported public integration APIs:

  • /, /index.php redirect to the report catalog.
  • /workspace.php renders the shell workspace.
  • /reports/index.php, /reports/view.php, /reports/report_runner.php.
  • /reports/publish_report.php, /reports/edit_report.php, /reports/delete_report.php.
  • /reports/datasources.php, /reports/generate_jasper_context.php, /reports/resource_sync.php.
  • /schedules.php, /edit_schedule.php, /executions.php, /history.php.
  • /recipients.php, /edit_recipient.php, /email_templates.php, /edit_email_template.php.

Report management forms rely on browser redirects/HTML and do not provide JSON success schemas. delete_report.php mutates state through GET, so it must not be called as an API. The access_groups string in report JSON is metadata; runtime authorization uses Central resource permissions instead.

Form-backed JSON action handlers

All handlers accept POST form fields (application/x-www-form-urlencoded or multipart/form-data), require a platform administrator when auth is enabled, perform no CSRF-token check, and normally return HTTP 200 even when success:false. They are UI implementation contracts, not a stable public API.

/action/schedule.php

Choose exactly one operation field:

  • delete=1, id — removes the schedule, timer, and environment file.
  • run_now=1, id — runs synchronously and returns execution_id, and on success output_file and email_status.
  • create=1 — creates a schedule; success includes id.
  • update=1, id — updates a schedule.

Create/update fields:

  • Required common fields: schedule_mode, report_name (alias name), datasource_name (alias datasource), format, and filename.
  • schedule_mode: once, repeat_minutes, hourly, daily, weekly, monthly, or custom.
  • Mode field: once_datetime; repeat_minutes (1–1440); hourly_minute (0–59); daily_time (HH:MM); weekly_day plus weekly_time; monthly_day (1–31) plus monthly_time; or five-field cron_custom.
  • format: scheduler-limited to pdf, xlsx, csv, html, xls, or docx.
  • Optional: enabled, email, email_subject (alias email_subj), email_body, email_template (alias email_tmpl), url_opt_params, and noemail. Unless noemail is truthy and not f, email is required.

Base response:

{"success":true,"message":"Schedule 12 created.","id":12}

Application DB failure is 503. Uncaught exceptions are 500 and currently expose the exception message in message.

/action/recipient.php

Save fields are optional integer id, optional name, required valid email, and optional notes. Delete uses delete=1&id={integer}. Responses contain only success and message; DB failure is 503.

/action/email_template.php

The handler is written to save id, required name, subject, and body, or delete with delete=1&id={integer}. It calls jrs_email_template_get/list/save/delete, but the loaded repository defines only file-template functions named jrs_email_tmpl_*. The route and related pages therefore appear nonfunctional and normally fail with undefined-function errors. Do not integrate with this handler until the implementation is repaired.