## Retrieve Sales Performance

Returns sales performance data for the authenticated merchant based on the specified date range.

The endpoint supports various input formats:
- Specific date: `YYYY-MM-DD` (e.g., "2024-01-15")
- Date range: `YYYY-MM-DD..YYYY-MM-DD` (e.g., "2024-01-01..2024-01-31")

The response includes aggregated metrics such as total sales, transaction count, and average transaction value.
**`exclude_voided`:** the default is `true` — only non-void transactions are counted. When `false`, voided transactions are included in those totals.

**Timezone Handling:**
The service uses the merchant's configured timezone for all date boundaries and grouping.
This ensures that payments are grouped according to the merchant's local date/time.
For example, a payment at 2025-10-09 22:51:28 UTC would appear in 2025-10-10 data for a merchant in timezone "Asia/Bangkok" (GMT+7).

### Granularity Logic

The response granularity is automatically determined based on the date range:
- **0 days** (single date): Hourly breakdown
- **1-83 days**: Daily breakdown
- **84-167 days**: Weekly breakdown
- **168+ days**: Monthly breakdown

This affects how the `transactions` array is structured and the `granularity` field in the response.

## Endpoint signature

```http
POST https://api.reservepay.com/merchants/retrieve-sales-performance HTTP/1.1
Content-Type: application/json
Accept: application/json
Authorization: Bearer <token>

{
  period: string,
  exclude_voided: boolean?,
  terminal_id: string?,
}
```

Returns: object

## Request arguments

### `period` (string)

**Required**. The date or date range for which to retrieve sales performance data.

**Supported formats:**
- **Specific date**: `YYYY-MM-DD` (e.g., "2024-01-15") - Returns hourly breakdown
- **Date range**: `YYYY-MM-DD..YYYY-MM-DD` (e.g., "2024-01-01..2024-01-31") - Returns daily/weekly/monthly breakdown based on range size

**Examples:**
- `"2024-01-15"` - Single day, hourly breakdown
- `"2024-01-01..2024-01-07"` - 7 days, daily breakdown
- `"2024-01-01..2024-03-31"` - 90 days, weekly breakdown
- `"2024-01-01..2024-12-31"` - 365 days, monthly breakdown

### `exclude_voided` (boolean)

_Optional_. Defaults to `true` (only non-void transactions). When `false`: voided transactions are included in the totals.

### `terminal_id` (string)

_Optional_. Optional. When provided, only sales captured on the specified terminal are included in the totals.

## Response attributes

### `start_date` (string)

**Always present**. The start date of the performance period in ISO 8601 format (YYYY-MM-DD).

This represents the beginning of the date range for which performance data is calculated.
For single day requests, this will be the same as end_date.

### `end_date` (string)

**Always present**. The end date of the performance period in ISO 8601 format (YYYY-MM-DD).

This represents the end of the date range for which performance data is calculated.
For single day requests, this will be the same as start_date.

### `amount` (number)

**Always present**. The total amount of all captured transactions in the period, expressed in the smallest currency unit. E.g. 100 THB is represented as 10000. And 100 JPY is represented as 100.

### `count` (number)

**Always present**. The total number of captured transactions in the period.

### `average` (number)

_Nullable_. The average captured transaction amount in the smallest currency unit.

### `change` (number)

_Nullable_. The percentage change in total amount compared to the previous equivalent period.

**Values:**
- **Positive**: Indicates an increase in compared to the previous period
- **Negative**: Indicates a decrease in compared to the previous period
- **Null**: When there are no transactions in the previous period (division by zero)

**Example:** A value of 15.5 means increased by 15.5% compared to the previous period.

### `granularity` (string)

**Always present**. The time granularity used for transaction breakdown in the response.

**Granularity is determined by the date range:**
- **hourly**: Single day requests (0 days)
- **daily**: 1-83 days range
- **weekly**: 84-167 days range
- **monthly**: 168+ days range

This affects how the transactions array is grouped and formatted.

Possible values:

- `hourly`
- `daily`
- `weekly`
- `monthly`

### `transactions` (array)

**Always present**. Array of transaction breakdowns grouped by the specified granularity.

**Each transaction object contains:**
- `total_amount`: Total amount for the period in smallest currency unit
- `total_count`: Number of transactions for the period
- `period_start`: Start of the period (format varies by granularity)

**Period start formats:**
- **hourly**: "HH:00:00" (e.g., "14:00:00")
- **daily**: "YYYY-MM-DD" ISO 8601 format (e.g., "2024-01-15")
- **weekly**: "YYYY-MM-DD" (week start date)
- **monthly**: "YYYY-MM-DD" (month start date)

**Note:** Array may be empty if no transactions exist for the specified date range.

## Errors specific to this endpoint

### `INVALID_DATE_FORMAT`

This error occurs when the date_input parameter is not in a supported format.
Please use one of the supported formats: YYYY-MM-DD, YYYY-MM-DD..YYYY-MM-DD, or keywords.

### `INVALID_DATE_RANGE`

This error occurs when the end date is before the start date in a date range.
Please ensure the end date is after or equal to the start date.

### `NOT_FOUND`

The terminal specified by `terminal_id` could not be found for this merchant.

## Errors common to all endpoints

### `UNHANDLED_ERROR`

This error occurs when the server encounters an unexpected internal error that
it cannot handle gracefully. This typically happens due to bugs, infrastructure
issues, or edge cases that weren't anticipated during development.

### `INVALID_ARGUMENTS`

This error occurs when the request contains invalid or missing parameters.
Common cases include missing required fields, or values that don't match the
expected format or type.

### `BAD_VERSION`

This error occurs when making requests to an API version that does not exist.
This commonly happens when using an outdated SDK or when the API version
specified in the request URL is incorrect.
