The PDF Report API allows API clients to asynchronously generate a downloadable PDF report for a connected SQR user. The flow is fully async: a job is enqueued immediately and processed in the background. Once the job completes, a time-limited pre-signed download URL is issued on demand.
All three endpoints are authenticated using a Bearer token obtained from the OAuth Token API.
Generating a PDF report is a three-step asynchronous process:
1. POST /v1/document/api → Enqueue a report job (returns 202 + jobId)
2. GET /v1/document/api/{id} → Poll until status is COMPLETE or FAILED
3. GET /v1/document/api/{id}/url → Retrieve the signed download URLPOST /v1/document/api
Submit a request to generate a PDF report for a specific user. The API responds immediately with 202 Accepted and returns a jobId. No report has been generated yet at this point; the job is placed in a processing queue.
Rate limit: Max 10 requests per 10 minutes per org.
Headers
Authorization: Bearer <access_token>
Content-Type: application/jsonBody
{
"userId": "US1A2B3C4D5E6F78"
}| Field | Type | Required | Description |
|---|---|---|---|
userId | string | Yes | The SQR user ID (AppUser.id) for whom the report is being generated. Must be 1–16 characters. |
{
"jobId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"status": "PENDING",
"userId": "US1A2B3C4D5E6F78",
"createdAt": "2025-05-05T10:00:00.000Z",
"updatedAt": "2025-05-05T10:00:00.000Z"
}Store the jobId — you will need it to check job status and retrieve the download URL.
GET /v1/document/api/{id}
Returns the current status and metadata of the report generation job. Poll this endpoint until status reaches a terminal state: COMPLETE or FAILED.
Headers
Authorization: Bearer <access_token>Path parameter
| Parameter | Type | Description |
|---|---|---|
id | string | The jobId returned in Step 1 |
{
"jobId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"status": "COMPLETE",
"userId": "US1A2B3C4D5E6F78",
"templateVersion": "v2",
"sizeBytes": 204800,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"durationMs": 1420,
"createdAt": "2025-05-05T10:00:00.000Z",
"updatedAt": "2025-05-05T10:00:02.000Z",
"completedAt": "2025-05-05T10:00:02.000Z"
}| Status | Description |
|---|---|
PENDING | Job is queued and waiting to be processed |
IN_PROGRESS | Job is currently being processed |
COMPLETE | Report generated successfully — download URL available |
FAILED | Report generation failed — see errorCode |
Poll at a reasonable interval to avoid unnecessary load. A recommended strategy is:
- Poll every 3–5 seconds for the first 30 seconds.
- If still not complete, back off to every 10–15 seconds.
- Treat any job that has not completed within 5 minutes as failed and surface an appropriate error to your user.
GET /v1/document/api/{id}/url
Once the job status is COMPLETE, request a time-limited pre-signed S3 URL to download the PDF report.
- The URL is valid for 5 minutes from the time it is issued.
- RBAC and org scope are re-validated on every call — URLs are never cached server-side.
- If the report is not yet complete, the API returns
422 Unprocessable Entity.
Headers
Authorization: Bearer <access_token>Path parameter
| Parameter | Type | Description |
|---|---|---|
id | string | The jobId returned in Step 1 |
{
"url": "https://s3.amazonaws.com/sqr-reports/...?X-Amz-Signature=...",
"expiresInSeconds": 300,
"filename": "SQR_J_Smith_ABCD.pdf"
}| Field | Type | Description |
|---|---|---|
url | string | Pre-signed S3 download URL, valid for 5 minutes |
expiresInSeconds | number | URL TTL in seconds (always 300) |
filename | string | Suggested filename to use when saving the PDF |
Use the url value to initiate a direct download from S3. The URL will expire after expiresInSeconds seconds and cannot be re-used. If you need to allow another download after expiry, simply call this endpoint again to receive a fresh URL.
| Status Code | Meaning |
|---|---|
401 | Missing or invalid Bearer token. Obtain a new token via the OAuth Token API. |
403 | Forbidden. The authenticated org does not have permission to access this user's report. |
404 | The specified userId (Step 1) or jobId (Steps 2–3) was not found. |
409 | A pending job already exists for this user. Wait for it to complete before creating a new one. |
422 | The report job is not yet complete (Step 3 only). Continue polling Step 2. |
429 | Rate limit exceeded. Maximum 10 requests per 10 minutes per org (Step 1 only). |
5XX | Internal server error. Contact support@sqr.id. |
# Step 1 — Create the job
POST /v1/document/api
Host: api.sqr-group.com
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...
Content-Type: application/json
{
"userId": "US1A2B3C4D5E6F78"
}
# → 202 Accepted
# {
# "jobId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
# "status": "PENDING",
# ...
# }
---
# Step 2 — Poll until COMPLETE
GET /v1/document/api/3fa85f64-5717-4562-b3fc-2c963f66afa6
Host: api.sqr-group.com
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...
# → 200 OK
# {
# "jobId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
# "status": "COMPLETE",
# ...
# }
---
# Step 3 — Get the download URL
GET /v1/document/api/3fa85f64-5717-4562-b3fc-2c963f66afa6/url
Host: api.sqr-group.com
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...
# → 200 OK
# {
# "url": "https://s3.amazonaws.com/...",
# "expiresInSeconds": 300,
# "filename": "SQR_J_Smith_ABCD.pdf"
# }