I missed your post communicating your successful test; the only missing component is the attachment.
What's missing from your script is the code snippet below:
reportBytes = reportAdminService.runReport(MXServer.getMXServer().getSystemUserInfo(), "asset_detail.rptdesign", "asset",parameterData, fileName, ReportAdminServiceRemote.OUTPUT_FORMAT_PDF)
assetSet=service.getMboSet("ASSET",MXServer.getMXServer().getSystemUserInfo())
assetSet.setWhere(whereclause)
assetMbo=assetSet.getMbo(0)
doclinkSet=assetMbo.getMboSet("DOCLINKS")
docStore=AttachmentStorage.getInstance()
doclinksMbo = doclinkSet.add()
newFileName=docStore.getAttachmentQualifiedName(doclinksMbo,fileName)
docStore.createAttachment(newFileName,reportBytes,"application/pdf")
doclinksMbo.setValue("URLTYPE", "FILE")
doclinksMbo.setValue("URLNAME", newFileName)
doclinksMbo.setValue("NEWURLNAME", newFileName)
doclinksMbo.setValue("DOCTYPE", "Attachments")
doclinksMbo.setValue("ADDINFO", True)
doclinksMbo.setValue("DESCRIPTION", "Test report", doclinksMbo.NOACCESSCHECK)
doclinksMbo.setValue("PRINTTHRULINK", False,doclinksMbo.NOACCESSCHECK)
assetSet.save()
assetSet.cleanup()
After modifying your script:
- Navigate to the Communication Template application
- Select the Communication Template > Attachment Folders Tab
- More than likely, the Attachment Document Folder exists
- Set the Send with Communication? flag to True (checked)
- Save
- Retest
Theoretically, implementing these changes yields the expected behavior.

Original Message:
Sent: 10-02-2025 08:22
From: Jason Johnson
Subject: Publish channels and Reports
I understand the communication template / escalation process. But how do you specify the "woprint.rptdesign" as an attachment? It has to be generated at run time; it itself is not an attachment to the work order.
------------------------------
Jason Johnson
RSI
Original Message:
Sent: 09-30-2025 22:07
From: FREDRICK NDWARU
Subject: Publish channels and Reports
A Different Approach to Consider
Using an escalation with a communication template and the report's attachment is considered one of the simplest and most maintainable methods for automating BIRT report delivery in Maximo.
Why This Method Is Simpler
No Custom Code Needed:
The whole process leverages Maximo's standard escalation and communication template features-no automation scripting or Java is required.
Point-and-Click Configuration:
Escalations can be set up using the UI to monitor conditions and trigger emails, while communication templates handle message formatting and report attachments.
Easier to Maintain:
Business users can adjust recipients, conditions, and template content without a developer. Reports are automatically attached if specified in the template.
How It Works
Create a Communication Template:
Specify the email subject/body, variable substitutions, and designate the report to be attached for the target record type.
Set Up an Escalation:
Configure it to monitor the target objects (e.g., work orders with specific status).
Set the escalation action to send the communication template when the condition is met.
Result:
When the escalation fires, Maximo automatically generates the BIRT report and attaches it to the outgoing email.
------------------------------
FREDRICK NDWARU
NBCUniversal
Original Message:
Sent: 09-30-2025 09:14
From: Jason Johnson
Subject: Publish channels and Reports
In case anyone else is interested, there is another method in the report admin service specifically for this.
Maximo 7.6.1.2 API - ReportAdminService
from psdi.server import MXServerfrom com.ibm.tivoli.maximo.report.birt.runtime import ReportParameterDatafrom com.ibm.tivoli.maximo.report.birt.admin import ReportAdminServiceRemotewoMbo = mbowonum = woMbo.getString("WONUM")# --- Run BIRT report with attachments ---reportAdminService = MXServer.getMXServer().lookup("BIRTREPORT")whereclause = "wonum='%s'" % wonumparameterData = ReportParameterData()parameterData.clearAllParameters()parameterData.addParameter("where", "(WORKORDER.wonum='"+wonum+"')")fileName = "WO_%s.pdf" % wonumfilePath = reportAdminService.runReportWithAttachments( MXServer.getMXServer().getSystemUserInfo(), "woprint.rptdesign", "WOTRACK", parameterData, fileName, ReportAdminServiceRemote.OUTPUT_FORMAT_PDF)# --- Send Email ---toAddress = "abc@xyz.com"fromAddress = "maxadmin@ibm.com"subject = "Record retention %s" % wonumbody = "Attached is the full Work Order report (including attachments) for WO %s." % wonumMXServer.getMXServer().sendEMail( toAddress, None, None, fromAddress, subject, body, None, [filePath], None)
------------------------------
Jason Johnson
RSI
Original Message:
Sent: 08-28-2025 08:52
From: Jason Johnson
Subject: Publish channels and Reports
I was able to send the report in an email as an attachment. The only thing left is to run the report to attachments in the final PDF. I'll trade the full code I have for an answer :)
from psdi.server import MXServer
from com.ibm.tivoli.maximo.report.birt.runtime import ReportParameterData
from com.ibm.tivoli.maximo.report.birt.admin import ReportAdminServiceRemote
from java.io import File
from java.io import FileOutputStream
from java.io import ByteArrayInputStream
woMbo = mbo
wonum = woMbo.getString("WONUM")
# --- Run BIRT report ---
reportAdminService = MXServer.getMXServer().lookup("BIRTREPORT")
parameterData = ReportParameterData()
parameterData.clearAllParameters()
parameterData.addParameter("where", "(WORKORDER.wonum='"+wonum+"')")
fileName = "WO_%s.pdf" % wonum
# Run report
reportBytes = reportAdminService.runReport(
MXServer.getMXServer().getSystemUserInfo(),
"woprint.rptdesign",
"WOTRACK",
parameterData,
fileName,
ReportAdminServiceRemote.OUTPUT_FORMAT_PDF
)
# --- Send Email ---
toAddress = "abc@xyz.com"
fromAddress = "maxadmin@ibm.com"
subject = "Closed Work Order %s Report" % wonum
body = "Attached is the full Work Order report (including attachments) for WO %s." % wonum
filePath = File.separator + "tmp" + File.separator + fileName
tempFile = File(filePath)
fos = FileOutputStream(tempFile)
fos.write(reportBytes)
fos.flush()
fos.close()
MXServer.getMXServer().sendEMail(
toAddress,
None,
None,
fromAddress,
subject,
body,
None,
[filePath],
None
)
if tempFile.exists():
tempFile.delete()
------------------------------
Jason Johnson
RSI
Original Message:
Sent: 08-27-2025 11:28
From: Jason Johnson
Subject: Publish channels and Reports
Thank you, your response led me to the error. I had the incorrect app name in the code (workorder instead of wotrack).
Last question would be is it possible to email this report as an attachment using a Communication Template in the script?
------------------------------
Jason Johnson
RSI
Original Message:
Sent: 08-27-2025 09:00
From: Steven Shull
Subject: Publish channels and Reports
The error message saying "workorder application" makes me think you used workorder instead of wotrack (or whatever the appropriate application is) in this section of the code.
reportBytes = reportAdminService.runReport(MXServer.getMXServer().getSystemUserInfo(), "asset_detail.rptdesign", "asset",parameterData, fileName, ReportAdminServiceRemote.OUTPUT_FORMAT_PDF)
It's confusing but the thing after the report is the application you are "running" the report in. In the case of asset, the object & app name match but in work order, it should be wotrack or one of the clones.
------------------------------
Steven Shull
Naviam
Original Message:
Sent: 08-26-2025 17:19
From: Jason Johnson
Subject: Publish channels and Reports
When the script is run, it throws the following error. The security should be configured correctly (MAXADMIN user is in MAXADMIN group). We have SAML implemented and can't log in as the MAXADMIN user, so I can't tell if it would run manually.


------------------------------
Jason Johnson
RSI
Original Message:
Sent: 08-19-2025 10:43
From: Steven Shull
Subject: Publish channels and Reports
Your best option would be to run the report from an automation script on the desired event. For example, when POs are approved, I have seen customers automate a send of the PO report to the vendor. An example script to execute the report & store as an attachment is below. You could change this to send an email or push the file some other way to another system.
from psdi.server import MXServer
from com.ibm.tivoli.maximo.report.birt.runtime import ReportParameterData
from com.ibm.tivoli.maximo.report.birt.admin import ReportAdminServiceRemote
from com.ibm.tivoli.maximo.oslc.provider import AttachmentStorage
reportAdminService = MXServer.getMXServer().lookup("BIRTREPORT")
whereclause="assetnum='11430'"
parameterData = ReportParameterData()
parameterData.clearAllParameters()
parameterData.addParameter("where", whereclause)
fileName="testfile.pdf"
reportBytes = reportAdminService.runReport(MXServer.getMXServer().getSystemUserInfo(), "asset_detail.rptdesign", "asset",parameterData, fileName, ReportAdminServiceRemote.OUTPUT_FORMAT_PDF)
assetSet=service.getMboSet("ASSET",MXServer.getMXServer().getSystemUserInfo())
assetSet.setWhere(whereclause)
assetMbo=assetSet.getMbo(0)
doclinkSet=assetMbo.getMboSet("DOCLINKS")
docStore=AttachmentStorage.getInstance()
doclinksMbo = doclinkSet.add()
newFileName=docStore.getAttachmentQualifiedName(doclinksMbo,fileName)
docStore.createAttachment(newFileName,reportBytes,"application/pdf")
doclinksMbo.setValue("URLTYPE", "FILE")
doclinksMbo.setValue("URLNAME", newFileName)
doclinksMbo.setValue("NEWURLNAME", newFileName)
doclinksMbo.setValue("DOCTYPE", "Attachments")
doclinksMbo.setValue("ADDINFO", True)
doclinksMbo.setValue("DESCRIPTION", "Test report", doclinksMbo.NOACCESSCHECK)
doclinksMbo.setValue("PRINTTHRULINK", False,doclinksMbo.NOACCESSCHECK)
assetSet.save()
assetSet.cleanup()
------------------------------
Steven Shull
Naviam
Original Message:
Sent: 08-19-2025 07:21
From: Jason Johnson
Subject: Publish channels and Reports
Our company is PDF-driven for record retention. Is it possible to export report PDF's using the MIF? For example, we are hoping to use an event (status changed to close) to then export the record's report (like woprint for work orders). The REST API works fine to pull reports, but we're hoping for a push.
#Administration
#Integrations
------------------------------
Jason Johnson
RSI
------------------------------