Enhanced Reports API Integration
View advanced built-in reports and create your own without any additional infrastructure.
One of PostGrid's main advantages over traditional direct mail companies is visibility. You're able to monitor the status of each individual mailer, get insights into its delivery, and export that data whenever you need it.
Enhanced reports extend PostGrid's capabilities to provide more detailed analytics (e.g. delivery velocity, mail categories, etc) and to let you create your own custom reports. Not only that, you can access these reports using our API as well as our dashboard, allowing you to build automations on top of them.
Reach out to [email protected] to get access.
Ad-Hoc Reports
One way to use PostGrid's enhanced reports system is to run ad-hoc SQL queries against your data lake. This lets get quick insights into your data without setting up a report. Here's a query that gets the id and status of all letters sent to a contact with a particular first name:
select l.id, l.status from letters l
join contacts c on c.id = l.to_id
where c.firstName = ?Let's run this query using the API to find all the letters sent to Kevin (API Reference)
curl --location 'https://api.postgrid.com/print-mail/v1/reports/samples' \
--header 'x-api-key: {YOUR_API_KEY}' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'sqlQuery=select l.id, l.status from letters l
join contacts c on c.id = l.to_id
where c.firstName = ?' \
--data-urlencode 'params[]=Kevin' \
--data-urlencode 'limit=5'Responds with
{
"id": "report_sample_qWvJDT7PCtpSw499WQfBx3",
"object": "report_sample",
"records": [
{
"id": "letter_bYuofk7EVPupccaMqitzG8",
"status": "completed"
},
{
"id": "letter_qJD9FaoHCrLuW9AsmtnMBP",
"status": "completed"
},
{
"id": "letter_44su5CvLkWQPd1ptoBHK4J",
"status": "completed"
},
{
"id": "letter_cezhbzY9s4Yk9art23f5gD",
"status": "completed"
},
{
"id": "letter_4d4fnfFTb1SU1QgNrSaJvq",
"status": "completed"
}
]
}These are letter IDs and statuses for letters that are sent to somebody with the first name Kevin. We're passing Kevin in as the first binding to the SQL query via params, preventing any SQL injection. This means you can safely pass untrusted data into params – e.g. letting your users query for all of their letters by first name.
Whilst the query that I've shown above could be replicated using PostGrid's structured search API , you can perform much more advanced queries using SQL. Here's another example where we get the average page count of all our letters (API Reference)
curl --location 'https://api.postgrid.com/print-mail/v1/reports/samples' \
--header 'x-api-key: {YOUR_API_KEY}' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'sqlQuery=select avg(pageCount) from letters'Responds with
{
"id": "report_sample_rsmfyTfMPZSsNGBKP9wCAG",
"object": "report_sample",
"records": [
{
"avg(pageCount)": 2.1316224253772442
}
]
}These are just some examples of what you can do with ad-hoc SQL queries. You have access to all the querying capabilities of DuckDB as documented here .
Limitations
These ad-hoc reports can only run for a maximum of 30s and return at most 1000 rows (you can specify at most 1000 for limit). Also, you can only at most run 2 queries per second. Please reach out to [email protected] if you would like a higher quota on any of these values.
Also, the data provided in these reports may be up to 2 hours behind your latest PostGrid data. If you need real-time data, we recommend listening to our webhooks or polling our GET endpoints.
Saved Reports
Once you've sampled a query, you may want to save it for future use, or you may need more than just 1000 rows of data.
You can create a saved report by hitting the POST /reports endpoint (API Reference)
curl --location 'https://api.postgrid.com/print-mail/v1/reports' \
--header 'x-api-key: {YOUR_API_KEY}' \
--header 'Content-Type: application/json' \
--data '{
"sqlQuery": "select * from letters where sendDate > ?::TIMESTAMP and sendDate < ?::TIMESTAMP"
}'This query simply gives me back all the letters which have a sendDate within a given time range. This gives me back a report ID and other details
{
"id": "report_8BriPzDkDChoUDZuBYcwb8",
"object": "report",
"live": false,
"sqlQuery": "select * from letters where sendDate > ?::TIMESTAMP and sendDate < ?::TIMESTAMP",
"createdAt": "2025-11-11T19:38:15.819Z",
"updatedAt": "2025-11-11T19:38:15.819Z"
}Now, I can sample this report by hitting POST /reports/report_8BriPzDkDChoUDZuBYcwb8/samples same as before. (API Reference)
I can also initiate a report export which lets me export up to 100 megabytes of data from PostGrid (API Reference)
curl --location 'https://api.postgrid.com/print-mail/v1/reports/report_8BriPzDkDChoUDZuBYcwb8/exports' \
--header 'x-api-key: {YOUR_API_KEY}' \
--header 'Content-Type: application/json' \
--data '{
"params": ["2025-04-01", "2025-04-30"]
}'Which responds with
{
"id": "report_export_3cyBHymXp6R2HLiHJjWpDn",
"object": "report_export",
"live": false,
"params": [
"2025-04-01",
"2025-04-30"
],
"report": {
"id": "report_cfUj47hyjWfoQP9boGFKsL",
"sqlQuery": "select * from letters where sendDate > ?::TIMESTAMP and sendDate < ?::TIMESTAMP"
},
"createdAt": "2025-11-11T19:41:17.114Z",
"updatedAt": "2025-11-11T19:41:17.114Z"
}I can then poll this for completion by hitting the GET /reports/report_cfUj47hyjWfoQP9boGFKsL/exports/report_export_3cyBHymXp6R2HLiHJjWpDn endpoint (API Reference)
{
"id": "report_export_3cyBHymXp6R2HLiHJjWpDn",
"object": "report_export",
"live": false,
"outputURL": "https://pg-prod-bucket-1.s3.amazonaws.com/report-exports/test/org_aSFrdfG2QGnS6vzx3BSAZt/report_export_3cyBHymXp6R2HLiHJjWpDn.csv?AWSAccessKeyId=AKIA5GFUILSULWTWCR64&Expires=1762891057&Signature=pqfy8%2B%2FGR7idaaiToTqYtsaVHDI%3D",
"params": [
"2025-04-01",
"2025-04-30"
],
"report": {
"id": "report_cfUj47hyjWfoQP9boGFKsL",
"sqlQuery": "select * from letters where sendDate > ?::TIMESTAMP and sendDate < ?::TIMESTAMP"
},
"rowCount": 186,
"sizeInBytes": 106413,
"createdAt": "2025-11-11T19:41:17.114Z",
"updatedAt": "2025-11-11T19:41:22.621Z"
}Once there is an outputURL populated, I can use this link to download the CSV file with all my data.
Limitations
As mentioned before, you can only export up to 100mb of data in that CSV file. PostGrid will truncate anything past that point. Moreover, your export can only be processed for a maximum of 10 minutes. Poorly structured queries that process 100s of millions of orders are likely to exceed this limit, so leverage parameters to scope down your queries as needed.
Updated about 9 hours ago
Check out https://postgrid.readme.io/docs/data-lake-schema# to view the schema of the SQL tables you can query.
