Reports API
The Reports-API lets merchants access their completed transaction reports programmatically. It’s designed for reconciliation, accounting, analytics, and compliance — without exposing any public storage links.
Two secure APIs are provided:
List Reports : Returns a filtered, paginated list of finished reports (auto or manual), plus a secure
download_action.Download Report : Downloads the binary file using authenticated access.
Why this matters: The dashboard already shows reports, but this API enables automated systems (ERP, BI tools, finance scripts) to fetch and download reports safely.
Base URL
Use your Ottu domain:
https://<ottu-url>Endpoints
1) List Reports
GET b/api/v1/reports2) Download Report
From the response of List Reports API, extract download_action.url for the desired report
make GET request to download_action.url to download the file
Supported Methods
For detailed information on authentication procedures, please refer to the Authentication documentation.
Permissions apply only when using Basic Auth.
Required permission
report.can_view_report
Rules
If the user does not have the permission, the API responds with:
403 Forbidden
Message like:
"No permission assigned"
API Key authentication does not require user permissions, since it is merchant-scoped.
Reports sources
Reports can be generated in two ways:
Auto reports: daily / weekly / monthly / yearly schedules.
Manual reports: created via dashboard.
Visibility and security rules
A merchant can only see their own reports.
Only finished reports are returned.
No public or raw storage URLs are ever returned.
Every download attempt is audit-logged.
Download workflow (high-level)
Call List Reports to get available reports.
Pick a report from
results.Use its secure
download_action.url.Call that URL with the same authentication headers.
The report file is returned as binary.

Retrieve a paginated list of completed transaction reports for reconciliation, accounting, analytics, and compliance purposes.
Authentication
API Key (Recommended):
Api-Key: your_private_api_keyBasic Auth: User must have
report.view_reportpermission
Example Request
curl -X GET 'https://your-domain.com/api/v1/reports/files/?created_after=2025-11-01&limit=50' \
-H 'Api-Key: your_private_api_key_here'Key Features
Only returns finished reports (optimized queries)
Includes
encrypted_idfor reference (prevents enumeration)Provides
download_actionwith ready-to-use secure download URLOrdered by creation date (newest first)
Merchant-isolated (each instance sees only their reports)
Response Fields
encrypted_id: Encrypted report identifier for referencedownload_action.url: Pre-signed download URL with embedded tokendownload_action.method: HTTP method to use (alwaysGET)
Integration Walkthrough
Step 1: Call this endpoint to list available reports
Step 2: From the response, extract download_action.url for the desired report
Step 3: Make a GET request to that URL (same auth headers) to download the file
Created after (inclusive)
Created before (inclusive)
Report interval
daily- Dailyweekly- Weeklymonthly- Monthlyyearly- Yearly
Number of results to return per page.
The initial index from which to return the results.
Report source
auto- Automanual- Manual
Private API key to be provided in the format Api-Key <key>.
Api-Key vSUmxsXx.V81oYvOWFMcIywaOu57Utx6VSCmG11loDownload a report file using the secure token from the list endpoint.
How It Works
Call
/api/v1/reports/files/to list reportsEach report includes a
download_actionobject with a pre-built URLUse that URL directly - the token is already embedded in the path
Authentication
API Key (Recommended):
Api-Key: your_private_api_keyBasic Auth: User must have
report.view_reportpermission
Example Flow
# Step 1: List reports
curl -X GET 'https://your-domain.com/api/v1/reports/files/' \
-H 'Api-Key: your_private_api_key_here'
# Response includes:
# {
# "encrypted_id": "abc123...",
# "download_action": {
# "method": "GET",
# "url": "https://your-domain.com/api/v1/reports/files/<token>/download/"
# }
# }
# Step 2: Download using the URL from download_action
curl -X GET 'https://your-domain.com/api/v1/reports/files/<token>/download/' \
-H 'Api-Key: your_private_api_key_here' \
-o report.csvSecurity Features
Token-based: Download tokens are UUIDs cached in Redis
Time-limited: Tokens expire (configurable TTL, default from settings)
User-bound: Token is tied to the user who requested the list
Rate Limiting: Downloads are rate-limited per user
Ownership Verification: Server verifies user owns the report
File Delivery
S3 Storage: Redirects (302) to a pre-signed S3 URL
Local Storage: Returns file with
X-Sendfileheader for Apache
File Formats
CSV:
text/csv- UTF-8 encoded, comma-delimitedXLSX:
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
Secure download token (UUID) from the download_action.url field in the list response. Tokens are time-limited and bound to the authenticated user.
Private API key to be provided in the format Api-Key <key>.
Api-Key vSUmxsXx.V81oYvOWFMcIywaOu57Utx6VSCmG11loReport file (CSV or XLSX). For S3: redirects to pre-signed URL.
Redirect to pre-signed S3 URL (when S3 storage is enabled)
Invalid token (unknown alias or malformed token)
User is not authorized to download this file
Report or file not found
Download link has expired or is invalid
1) List Reports
Purpose: Retrieve a paginated list of completed reports.
Request
Query parameters
created_after
date
No
Lower bound (inclusive)
created_before
date
No
Upper bound (inclusive)
interval
enum
No
daily, weekly, monthly, yearly
source
enum
No
auto or manual
limit
int
No
Default 50, max 200
offset
int
No
Pagination mode (cursor recommended if enabled)
Response
download_action.url– pre-signed download URL with embedded token.download_action.method– alwaysGET.
2) Download Report
Purpose Download the report file as binary.
Request
Response
Returns the file directly (CSV, XLSX, etc.) as binary.
No JSON body unless there’s an error.
Use API Key for automation
More stable and permission-free for system integrations.
Always filter by date
Avoid pulling large histories unintentionally.
Example: fetch only last month’s reports.
Respect pagination
Use
limitandcursor/offsetuntilnextis null.
Handle empty results
A valid response can be:
Log your own download tracking
Even though Ottu logs downloads, your system should store:
report id
download time
success state
Retry safely
On
429 rate_limited, backoff before retrying.
1️Can I download reports without listing them first?
You technically can if you already stored the encrypted_id.
But listing first is the safest way to discover available reports.
2️Why don’t I see reports that are still generating?
The List Reports API returns finished reports only to keep results correct and fast.
3️What happens if I don’t pass date filters?
The API returns reports from the last 30 days, newest first.
4️Can I share download links publicly?
No. Download URLs are secure, tokenized, and require authentication. They are not permanent or public.
5️What errors should I expect?
400
invalid_parameters
Bad filters
created_before < created_after
401
unauthorized
Invalid/missing auth
Header missing or wrong
403
forbidden
Insufficient permissions
Basic user lacks report permission
404
not_found
Report not found
Wrong or inaccessible ID
429
rate_limited
Too many requests
Quota exceeded
6️ I’m using Basic Auth but still getting 403 — why?
Your user is missing report.can_view_report.
Ask your admin to enable report API access.
7️ Are downloads logged even if they fail?
Yes. Every attempt is logged with outcome status for audit compliance.
Last updated