> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.andel.org/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.andel.org/_mcp/server.

# List purchases

GET https://api.andel.org/exchange/v1/purchases

List purchases visible to the authenticated tenant, ordered by
`purchased_at` descending. Use cursor pagination via `since` and `limit`.


Reference: https://docs.andel.org/dataexchange/data-exchange-api/purchases/list-purchases

## Authentication

- `Authorization` header (bearer token, required) — Production machine-to-machine flow. Tokens issued by Descope.
- `Authorization` header (bearer token, required) — Developer-exploration flow with PKCE. Used by Postman Guided Auth.

## Servers

- `https://api.andel.org/exchange/v1` (Production, default)
- `https://7403d846-765d-4d63-9e5c-b7f0ab21a354.mock.pstmn.io/exchange/v1` (Postman mock server (sandbox; auth is not enforced))

## Request

### Query parameters

- `member_id` (string, optional) — Filter purchases to a single member.
- `plan_id` (string, optional) — Filter purchases to a single plan. Must be one of the plans the token is authorized for; otherwise the API returns `403 Forbidden`.
- `ndc` (string, optional) — Filter to a single NDC-11 drug code.
- `prescriber_spi` (string, optional) — Filter to purchases written by a specific prescriber (Surescripts SPI).
- `event_type` (enum, optional) — Filter purchases to a single event type (e.g., only reversals).
  - Allowed values: `claim`, `reversal`, `adjustment`, `hra_initial_load`, `hra_rollover`, `hra_incentive`
- `status` (enum, optional) — Filter purchases by processing status (e.g., only rejected).
  - Allowed values: `accepted`, `rejected`, `pended`, `reversed`
- `since` (string, optional) — Cursor or ISO 8601 UTC timestamp. Returns purchases after this point.
- `until` (datetime, optional) — ISO 8601 UTC timestamp upper bound (exclusive).
- `limit` (integer, optional, default: 100) — Max results per page.

## Response

### 200

A page of purchases.

- `data` (list of object, required)
  - `purchase_id` (string, required) — Andel-issued unique identifier.
  - `member_id` (string, required) — Plan or PBM member identifier.
  - `plan_id` (string, required) — Plan that the member belongs to. Each member belongs to exactly one plan. Tokens are scoped to a set of allowed plan IDs; purchases for plans outside that set are not returned.
  - `purchased_at` (datetime, required) — ISO 8601 UTC timestamp from the pharmacy point-of-sale.
  - `currency` (string, required, default: USD) — ISO 4217 currency code.
  - `date_of_service` (date, required) — The actual fill date used for eligibility validation. Distinct from `purchased_at`, which is the point-of-sale timestamp.
  - `event_type` (enum, required, default: claim) — The kind of accumulator event. `claim` is a normal fill; `reversal` restores accumulators for a returned or voided fill; `adjustment` is a flat or paired correction.
    - Allowed values: `claim`, `reversal`, `adjustment`, `hra_initial_load`, `hra_rollover`, `hra_incentive`
  - `ndc` (string, optional) — 11-digit National Drug Code.
  - `prescriber_spi` (string, optional) — Surescripts Prescriber ID.
  - `member_purchase_amount` (double, optional) — (Proposed - provenance pending) Total amount the member paid at point-of-sale, USD.
  - `oop_amount` (double, optional) — (Proposed - provenance pending) Member out-of-pocket portion, USD.
  - `plan_contribution` (double, optional) — (Proposed - provenance pending) Plan's portion of the purchase (the plan contribution), USD.
  - `quantity` (integer, optional) — Units dispensed.
  - `days_supply` (integer, optional) — Days of therapy the dispensed quantity covers.
  - `provider_type` (enum, optional) — Qualifier describing which provider identifier is carried in the provider slot.
    - Allowed values: `ncpdp`, `npi`, `dea`, `copay_assist`
  - `pharmacy_npi` (string, optional) — Dispensing pharmacy identifier, when provided.
  - `network_ind` (enum, optional) — Whether the fill adjudicated in- or out-of-network.
    - Allowed values: `in_network`, `out_of_network`, `both`, `inn_house`
  - `original_purchase_id` (string, optional, nullable) — For reversals or adjustments, the `purchase_id` of the purchase being corrected. Null for new purchases.
  - `status` (enum, optional) — Processing status of the purchase.
    - Allowed values: `accepted`, `rejected`, `pended`, `reversed`
  - `deductible_applied` (double, optional) — (Proposed - provenance pending) Amount of this purchase applied to the member's deductible, USD.
  - `subscriber_id` (string, optional) — The member's subscriber identifier at the PBM's eligibility system. Distinct from `member_id`.
  - `first_name` (string, optional) — Member first name.
  - `last_name` (string, optional) — Member last name.
  - `date_of_birth` (date, optional) — Member date of birth.
  - `gender` (enum, optional) — Member gender as carried to the PBM.
    - Allowed values: `unknown`, `male`, `female`, `non_binary`
  - `relationship` (enum, optional) — Member's relationship to the subscriber.
    - Allowed values: `subscriber`, `spouse`, `dependent`, `student`, `disabled_dependent`, `adult_dependent`, `domestic_partner`
  - `accumulators` (list of object, optional) — (Proposed - provenance pending) Per-accumulator deltas this purchase applies (deductible, out-of-pocket, HRA, caps). A single fill can apply against up to six accumulators at once.
    - `type_of_benefit_account` (enum, required) — Which benefit accumulator this delta applies to.
      - Allowed values: `hra`, `deductible`, `oop`, `cap`, `lifetime_cap`, `drug_cap`, `benefit_deductible`, `benefit_oop`, `base_deductible`, `base_oop`, `tmoop`
    - `amount` (double, required) — (Proposed - provenance pending) Dollars applied to this accumulator on this purchase, USD.
    - `cr_db_indicator` (enum, required) — `debit` consumes the accumulator, `credit` restores it (a reversal), `replace` overwrites the running total, `bypass` ignores this accumulator for this transaction.
      - Allowed values: `debit`, `credit`, `replace`, `bypass`
    - `participation_type` (enum, optional) — Network level this accumulator tracks (may differ per accumulator).
      - Allowed values: `in_network`, `out_of_network`, `combined`, `inn_house`
    - `accumulated_amount` (double, optional) — (Proposed - provenance pending) Running total applied to date, USD. Required by ESI for `replace`.
    - `remaining_amount` (double, optional) — (Proposed - provenance pending) Amount left before the accumulator cap is met, USD.
    - `met_this_transaction` (boolean, optional) — True when this purchase drove `remaining_amount` to zero (e.g., deductible met on this fill).
  - `origin_code` (enum, optional) — ESI origin code for HRA balance events (`hra_initial_load`, `hra_rollover`, `hra_incentive`); `E` is a non-shared pharmacy dollars load. Omitted for pharmacy fills.
    - Allowed values: `E`, `R`
  - `plan_year` (integer, optional) — Plan year the balance applies to. Used for HRA balance events.
  - `esi` (object, optional) — ESI wire-protocol identifiers, populated when a purchase is exchanged via the ESI CDH format. All fields optional.
    - `sender_id` (string, optional) — ESI-assigned trading-partner sender identifier.
    - `receiver_id` (string, optional) — Receiver identifier; `MHS` when sending to ESI.
    - `signature` (string, optional) — 26-character composite transaction key (date + milliseconds + sequence + source-app code).
    - `claim_id` (string, optional) — ESI claim identifier.
    - `claim_xref_id` (string, optional) — Original-transaction reference on a reversal or adjustment. Mirrors `original_purchase_id`.
    - `transmission_type` (enum, optional) — Data Request (sent) vs Data Response (acknowledged).
      - Allowed values: `DQ`, `DR`
    - `request_code` (enum, optional) — Claim / Reversal / Adjustment request code.
      - Allowed values: `01`, `02`, `04`
    - `response_code` (string, optional) — ESI Data Response code; `00` is accepted, otherwise an error code.
    - `reason_code` (string, optional) — Granular reason detail beyond the response code.
- `next_cursor` (string, required, nullable) — Pass as `since` to fetch the next page. Null when no more pages.

## Examples

**Response**

```json
{
  "data": [
    {
      "purchase_id": "7e3a3c5e-3b7f-4f0a-9e65-1c9c3a8b1234",
      "member_id": "M-987654321",
      "plan_id": "PLN-0001",
      "purchased_at": "2026-05-13T18:24:01Z",
      "currency": "USD",
      "date_of_service": "2026-05-13",
      "event_type": "claim",
      "ndc": "00093005301",
      "prescriber_spi": "1234567890",
      "member_purchase_amount": 42.5,
      "oop_amount": 10,
      "plan_contribution": 32.5,
      "quantity": 30,
      "days_supply": 30,
      "provider_type": "npi",
      "network_ind": "in_network",
      "status": "accepted"
    },
    {
      "purchase_id": "4a2b9c11-1f6c-49aa-bc0e-7c2e8b1f4444",
      "member_id": "M-987654321",
      "plan_id": "PLN-0001",
      "purchased_at": "2026-04-29T14:11:55Z",
      "currency": "USD",
      "date_of_service": "2026-04-29",
      "event_type": "claim",
      "ndc": "50580048801",
      "prescriber_spi": "1234567890",
      "member_purchase_amount": 18.75,
      "oop_amount": 5,
      "plan_contribution": 13.75,
      "quantity": 90,
      "status": "accepted"
    }
  ],
  "next_cursor": "2026-04-29T14:11:55Z"
}
```

**SDK Code**

```python A page of purchases
import requests

url = "https://api.andel.org/exchange/v1/purchases"

headers = {"Authorization": "Bearer <token>"}

response = requests.get(url, headers=headers)

print(response.json())
```

```javascript A page of purchases
const url = 'https://api.andel.org/exchange/v1/purchases';
const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go A page of purchases
package main

import (
	"fmt"
	"net/http"
	"io"
)

func main() {

	url := "https://api.andel.org/exchange/v1/purchases"

	req, _ := http.NewRequest("GET", url, nil)

	req.Header.Add("Authorization", "Bearer <token>")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby A page of purchases
require 'uri'
require 'net/http'

url = URI("https://api.andel.org/exchange/v1/purchases")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'

response = http.request(request)
puts response.read_body
```

```java A page of purchases
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.get("https://api.andel.org/exchange/v1/purchases")
  .header("Authorization", "Bearer <token>")
  .asString();
```

```php A page of purchases
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('GET', 'https://api.andel.org/exchange/v1/purchases', [
  'headers' => [
    'Authorization' => 'Bearer <token>',
  ],
]);

echo $response->getBody();
```

```csharp A page of purchases
using RestSharp;

var client = new RestClient("https://api.andel.org/exchange/v1/purchases");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <token>");
IRestResponse response = client.Execute(request);
```

```swift A page of purchases
import Foundation

let headers = ["Authorization": "Bearer <token>"]

let request = NSMutableURLRequest(url: NSURL(string: "https://api.andel.org/exchange/v1/purchases")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```