Attachments
Users can attach files (for example receipts or invoices) to their transactions in the Lunar app. The Attachments endpoints let authorized Third Party Providers (TPPs) list and retrieve those attachments as signed download URLs.
These endpoints require the PSP_AI (Account Information) scope.
Discover which attachments a transaction has via the attachmentIds array on
the Transaction object
returned by the transaction list,
Transactions v2, and
get-by-id endpoints. Each ID
in that array can be fetched with the single-attachment endpoint below.
List Attachments
List all attachments for a transaction.
GET /accounts/{accountId}/transactions/{transactionId}/attachmentsPath Parameters
| Parameter | Type | Description |
|---|---|---|
accountId | string | The account identifier |
transactionId | string | The transaction identifier |
Response Structure
The response is an AttachmentListResponse object:
| Field | Type | Description |
|---|---|---|
attachments | Attachment[] | The attachments for the transaction (see below) |
Example
{
"attachments": [
{
"attachmentId": "00000000-0000-0000-0000-000000000001",
"fileId": "00000000-0000-0000-0000-000000000001",
"mimeType": "image/jpeg",
"downloadUrl": "https://storage.lunar.app/00000000-0000-0000-0000-000000000001/00000000-0000-0000-0000-000000000001.jpeg?Expires=1783074480&Signature=EXAMPLE_SIGNATURE&Key-Pair-Id=EXAMPLE_KEY_PAIR_ID"
},
{
"attachmentId": "00000000-0000-0000-0000-000000000002",
"fileId": "00000000-0000-0000-0000-000000000002",
"mimeType": "application/pdf",
"downloadUrl": "https://storage.lunar.app/00000000-0000-0000-0000-000000000002/00000000-0000-0000-0000-000000000002.pdf?Expires=1783074480&Signature=EXAMPLE_SIGNATURE&Key-Pair-Id=EXAMPLE_KEY_PAIR_ID"
}
]
}Get Attachment
Retrieve a single attachment by its identifier.
GET /accounts/{accountId}/transactions/{transactionId}/attachments/{attachmentId}Path Parameters
| Parameter | Type | Description |
|---|---|---|
accountId | string | The account identifier |
transactionId | string | The transaction identifier |
attachmentId | string | The attachment identifier |
Returns a single Attachment object.
Attachment object
| Field | Required | Description |
|---|---|---|
attachmentId | Yes | The unique ID of the attachment (matches an entry in the transaction’s attachmentIds) |
fileId | Yes | The storage file ID backing the attachment |
mimeType | No | The MIME type of the attachment, if known (e.g. image/jpeg, application/pdf) |
downloadUrl | Yes | A signed URL for downloading the attachment (see below) |
Signed download URLs
The downloadUrl is a signed URL that grants temporary access to download the
attachment directly from Lunar’s storage service. It carries the signature and an
expiry in its query string:
https://storage.lunar.app/00000000-0000-0000-0000-000000000001/00000000-0000-0000-0000-000000000001.jpeg?Expires=1783074480&Signature=EXAMPLE_SIGNATURE&Key-Pair-Id=EXAMPLE_KEY_PAIR_ID| Query parameter | Description |
|---|---|
Expires | Unix epoch timestamp (seconds) at which the URL stops working — e.g. 1783074480 |
Signature | The signature authorizing access to the file |
Key-Pair-Id | Identifier of the key pair used to sign the URL |
The signed URL expires 5 minutes after it is issued. The exact expiry is
encoded in the Expires query parameter (a Unix epoch timestamp), so download
the file before that time. If a URL has expired, re-request the attachment to
obtain a fresh one.
Required Scope
| Endpoint | Required Scope |
|---|---|
GET /accounts/{accountId}/transactions/{transactionId}/attachments | PSP_AI |
GET /accounts/{accountId}/transactions/{transactionId}/attachments/{attachmentId} | PSP_AI |
Error Handling
| Status | Description |
|---|---|
400 | Invalid request parameters |
403 | The access token was not found or grants no access |
404 | The attachment (or transaction/account) is not found or not accessible |
500 | Internal server error |
Missing, inaccessible, and not-yet-processed attachments all return the same
404. This is deliberate: it prevents a caller from distinguishing between an
attachment that does not exist, one it is not allowed to see, and one that is
still being processed.
Error responses include an errorCode and message for debugging.