List report files
Returns one entry for each UTC day in [start_date, end_date] that has a file, in date order, each with a signed GET link to that day's file. A day with no transactions still has a file, with no rows. A day with no entry is a day the export has not written yet, such as the current UTC day or a day whose export is late; it does not mean the day had no transactions, so call again later for that day. Days before first_date never get a file, because the shop's export of that type and format started on first_date. A shop that has no file of the requested type and format on any day gets FAILED_PRECONDITION instead. Stash turns a shop's export on, and it writes the first file, before the partner is told that the report is available; so this error means the report is not available for the shop yet: do not retry, contact Stash. The files use the same columns as the transaction reports in Stash Studio. Each row is one event: a payment, a refund or a dispute step. A later refund or dispute step is a new row on its own day; it does not change the payment's row. The record_id column is a stable ID of the event: the same event has the same record_id in every file. Use it to remove rows that two pulls share, and keep the row from the later pull. Columns are added only at the end, and a column is renamed or removed only with advance notice, so read the files by column name, not by position. A SETTLED day that is not final can still change; pull it again until is_final is true. SETTLED days become final together with their UTC calendar month, when Stash closes the month, usually 1 to 5 days after it ends. CHARGE days are never final, because their rows change while their charges settle, so do not wait for is_final on a CHARGE day. Stash gives no stop signal for a CHARGE day: follow it for as long as you need its unsettled rows, and use SETTLED for figures that become final. To know when to download a day again, compare its content_hash with the copy you hold: every change to the file's bytes gives a new content_hash, and the same bytes always give the same content_hash. as_of is the time of the data snapshot that each file was written from. Every link is valid until download_url_expires_at, 15 minutes after the response; call again for fresh links. This method accepts only the versioned x-stash-hmac-signature header, signed over the request body exactly as sent; the legacy stash-hmac-signature header is rejected with HTTP 401 (UNAUTHENTICATED), because it carries no timestamp and a captured request could be replayed. The shop in the signature header must equal the shop_id in the path. Repeated calls are safe, so retry after UNAVAILABLE or a timeout with a fresh timestamp and signature. Returns HTTP 401 (UNAUTHENTICATED) when the signature is missing, invalid, outside the time window, sent in the legacy header, or names a different shop or one Stash does not know; HTTP 400 (INVALID_ARGUMENT) when report_type or report_format is unspecified or unknown, a date is missing or is not YYYY-MM-DD, end_date is before start_date, or the range is longer than 31 days; HTTP 400 (FAILED_PRECONDITION) when the shop has no file of the requested type and format on any day; and HTTP 503 (UNAVAILABLE) when the files could not be listed, in which case retry. The two HTTP 400 cases differ only by the code in the response body: 3 for INVALID_ARGUMENT, 9 for FAILED_PRECONDITION. Do not retry UNAUTHENTICATED or INVALID_ARGUMENT unchanged: correct the signature or the request first, then send it again with a fresh timestamp and signature.
Authorization
hmac Versioned HMAC-SHA256 signature authenticating server-to-server SDK requests (your backend calling Stash), as opposed to client-side SDK operations. Recommended over the deprecated X-Stash-Api-Key for the best security. Header format: v1;{appId};{unixMillisTimestamp};{base64Signature} (semicolon-delimited). {base64Signature} is the base64-encoded HMAC-SHA256 of the string {unixMillisTimestamp}.{requestBody} using your app ingress secret (the ingress secret is shown base64-encoded in Studio; base64-decode it to the raw bytes used as the HMAC key), where {requestBody} is the request body exactly as you send it for POST and PUT requests (the compact canonical request JSON is also accepted) and empty for GET requests. A signature over the exact bytes verifies for bodies of up to 18 KiB (18,432 bytes); a larger body may be refused with 401 even when correctly signed. The timestamp must be within 5 minutes of Stash server time. Your appId is your immutable app identifier, shown in Stash Studio under Project Settings > App details; your ingress secret is under Project Settings > API Secrets.
In: header
Path Parameters
Shop identifier from Stash Studio. Must equal the shop in the x-stash-hmac-signature header.
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Request to list a shop's report files for a range of UTC days. The shop is taken from the path. Signed over the request body exactly as sent.
Response Body
application/json
application/json
curl -X POST "https://example.com/sdk/studio/string/reports/files" \ -H "Content-Type: application/json" \ -d '{ "reportType": "REPORT_TYPE_UNSPECIFIED", "reportFormat": "REPORT_FORMAT_UNSPECIFIED", "startDate": "string", "endDate": "string" }'{ "files": [ { "date": "string", "isFinal": true, "sizeBytes": "string", "downloadUrl": "string", "asOf": "2019-08-24T14:15:22Z", "contentHash": "string" } ], "downloadUrlExpiresAt": "2019-08-24T14:15:22Z", "firstDate": "string"}How is this guide?
Get prices GET
Retrieves uploaded pricing sheet data for the shop associated with the API key, filtered by region. Returns paginated price entries.
Generate authenticated URL POST
Generates an authenticated webshop URL for a player that signs them in when opened. target selects the page it opens: DEFAULT or ROOT for the webshop's root page, HOME for the home page, STORE for the store page, LOYALTY for the loyalty club page, or DAILY_STREAK for the daily streak page. Authenticate the request with an HMAC signature of the request body, or with the deprecated API key. This is a server-side endpoint and must not be called from the game client.