> For the complete documentation index, see [llms.txt](https://docs.onside.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.onside.io/sdk/purchase-validation/signed-in-apps-history.md).

# Signed In-App Purchase History

OnsideKit can produce a **signed** in-app purchase history as a compact JWS (JSON Web Signature) for the current user. Send it (or the order IDs it contains) to your backend to validate purchases — see [Backend Validation & Merchant API](/sdk/purchase-validation/merchant-api.md).

## Create the request

```swift
@MainActor static func makeSignedInAppsHistoryRequest()
    -> Result<OnsideSignedInAppsHistoryRequest, OnsideSignedInAppsHistoryRequestError>
```

The call returns a request object on success, or a pre-flight error:

```swift
switch Onside.makeSignedInAppsHistoryRequest() {
case .success(let request):
    request.delegate = self
    self.historyRequest = request   // retain it
    request.start()

case .failure(let error):
    // .notLoggedIn or .notSupportedInLocalTesting (pre-flight),
    // or a network error.
    print("Couldn't create history request: \(error)")
}
```

{% hint style="info" %}
This API requires an authenticated user — it returns `.notLoggedIn` if there is no session (it does **not** trigger login). In [local-testing](/sdk/advanced-and-tooling/local-testing.md) mode it returns `.notSupportedInLocalTesting`.
{% endhint %}

## The request object

```swift
protocol OnsideSignedInAppsHistoryRequest: AnyObject {
    @MainActor var delegate: OnsideSignedInAppsHistoryRequestDelegate? { get set }
    @MainActor func start()
    @MainActor func stop()
}
```

Retain the request for the whole operation (a dropped reference is cancelled). Use `stop()` to cancel.

## Handle the result

```swift
extension MyValidator: OnsideSignedInAppsHistoryRequestDelegate {

    func onsideSignedInAppsHistoryRequest(
        _ request: OnsideSignedInAppsHistoryRequest,
        didReceive response: OnsideSignedInAppsHistory
    ) {
        // response.data is the raw JWS blob; response.string is its UTF-8 form.
        sendToBackend(response.data)
    }

    func onsideSignedInAppsHistoryRequest(
        _ request: OnsideSignedInAppsHistoryRequest,
        didFailWithError error: OnsideSignedInAppsHistoryRequestError
    ) {
        print("History request failed: \(error)")
    }

    // Optional — always called after success or failure.
    func onsideSignedInAppsHistoryRequestDidFinish(
        _ request: OnsideSignedInAppsHistoryRequest
    ) {
        self.historyRequest = nil
    }
}
```

### The history value

```swift
struct OnsideSignedInAppsHistory {
    var data: Data        // the raw JWS blob
    var string: String?   // a UTF-8 decoding of `data`, when valid
}
```

`string` is a convenience that UTF-8-decodes `data`; the JWS is normally a printable string, so it is usually non-`nil`.

## Errors

`OnsideSignedInAppsHistoryRequestError`:

<table><thead><tr><th width="280">Case</th><th>Cause</th></tr></thead><tbody><tr><td><code>.notLoggedIn</code></td><td>No authenticated user (this API does not trigger login).</td></tr><tr><td><code>.notSupportedInLocalTesting</code></td><td>Running with a <code>.storekit</code> local-testing configuration.</td></tr><tr><td><code>.connectionError</code></td><td>Network failure.</td></tr><tr><td><code>.serviceUnavailable</code></td><td>Server returned 5xx.</td></tr><tr><td><code>.appNotRegistered</code></td><td>The app/install isn't recognized by Onside (HTTP 404).</td></tr><tr><td><code>.cancelled</code></td><td>The request was cancelled.</td></tr><tr><td><code>.internalError</code></td><td>Parsing or other unexpected error.</td></tr></tbody></table>

Once your backend has the signed history (or the order IDs from it), continue with [Backend Validation & Merchant API](/sdk/purchase-validation/merchant-api.md).


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.onside.io/sdk/purchase-validation/signed-in-apps-history.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
