# API Documentation

Everything you need to interact with AccessGrid.

## List Ledger Items

Retrieve a paginated list of ledger items (billing transactions) for your account. Supports filtering by date range. Each item includes the associated access pass and card template details when available.

### Parameters

#### page

nullable integer

Page number for pagination. Defaults to 1

#### per_page

nullable integer

Number of items per page (1-100). Defaults to 50

#### start_date

nullable datetime

Filter items created on or after this date. Must be in ISO8601 format

#### end_date

nullable datetime

Filter items created on or before this date. Must be in ISO8601 format

### Request

```bash
# Build the JSON payload (server only verifies SIG against sig_payload;
# filter params travel as ordinary query params)
PAYLOAD="{}"

# Sign the payload
PAYLOAD_B64=$(printf '%s' "$PAYLOAD" | openssl base64 -A)
SIG=$(printf '%s' "$PAYLOAD_B64" | openssl dgst -sha256 -hmac "$SECRET_KEY" -hex | awk '{print $NF}')

# Send curl request
curl -v -G \
-H "X-ACCT-ID: $ACCOUNT_ID" \
-H "X-PAYLOAD-SIG: $SIG" \
--data-urlencode "page=1" \
--data-urlencode "per_page=50" \
--data-urlencode "start_date=2025-01-01T00:00:00Z" \
--data-urlencode "end_date=2025-12-31T23:59:59Z" \
--data-urlencode "sig_payload=$PAYLOAD" \
"https://api.accessgrid.com/v1/console/ledger-items"
```

```ruby
require 'accessgrid'

acct_id = ENV['ACCOUNT_ID']
secret_key = ENV['SECRET_KEY']

client = AccessGrid.new(acct_id, secret_key)

items = client.console.ledger_items(
  page: 1,
  per_page: 50,
  start_date: 30.days.ago.utc.iso8601(3),
  end_date: Time.zone.now.utc.iso8601(3)
)

items.each do |item|
  puts "Amount: #{item.amount}, Kind: #{item.kind}, Date: #{item.created_at}"
  if item.access_pass
    puts "  Access Pass: #{item.access_pass.ex_id}"
    puts "  Card Template: #{item.access_pass.pass_template.ex_id}" if item.access_pass.pass_template
  end
end
```

```javascript
import AccessGrid from 'accessgrid';

const accountId = process.env.ACCOUNT_ID;
const secretKey = process.env.SECRET_KEY;

const client = new AccessGrid(accountId, secretKey);

const getLedgerItems = async () => {
  try {
    const result = await client.console.ledgerItems({
      page: 1,
      perPage: 50,
      startDate: new Date(Date.now() - 30 * 24 * 60 * 60 * 1000).toISOString(),
      endDate: new Date().toISOString()
    });

result.ledgerItems.forEach(item => {
      console.log(`Amount: ${item.amount}, Kind: ${item.kind}, Date: ${item.createdAt}`);
      if (item.accessPass) {
        console.log(`  Access Pass: ${item.accessPass.exId}`);
        if (item.accessPass.passTemplate) console.log(`  Card Template: ${item.accessPass.passTemplate.exId}`);
      }
    });

console.log(`Page ${result.pagination.currentPage} of ${result.pagination.totalPages}`);
  } catch (error) {
    console.error('Error fetching ledger items:', error);
  }
};

getLedgerItems();
```

```python
from accessgrid import AccessGrid
import os
from datetime import datetime, timezone, timedelta

account_id = os.getenv('ACCOUNT_ID')
secret_key = os.getenv('SECRET_KEY')

client = AccessGrid(account_id, secret_key)

start_date = (datetime.now(timezone.utc) - timedelta(days=30)).isoformat()
end_date = datetime.now(timezone.utc).isoformat()

result = client.console.ledger_items(
    page=1,
    per_page=50,
    start_date=start_date,
    end_date=end_date
)

for item in result['ledger_items']:
    print(f"Amount: {item['amount']}, Kind: {item['kind']}, Date: {item['created_at']}")
    if item.get('access_pass'):
        print(f"  Access Pass: {item['access_pass']['ex_id']}")
        if item['access_pass'].get('pass_template'):
            print(f"  Card Template: {item['access_pass']['pass_template']['ex_id']}")
```

```go
package main

import (
    "context"
    "fmt"
    "os"
    "time"
    "github.com/Access-Grid/accessgrid-go"
)

func main() {
    accountID := os.Getenv("ACCOUNT_ID")
    secretKey := os.Getenv("SECRET_KEY")

client, err := accessgrid.NewClient(accountID, secretKey)
    if err != nil {
        fmt.Printf("Error creating client: %v\n", err)
        return
    }

startDate := time.Now().AddDate(0, 0, -30).UTC()
    endDate := time.Now().UTC()
    params := accessgrid.ListLedgerItemsParams{
        Page:    1,
        PerPage: 50,
        StartDate: &startDate,
        EndDate:   &endDate,
    }

ctx := context.Background()
    result, err := client.Console.ListLedgerItems(ctx, params)
    if err != nil {
        fmt.Printf("Error fetching ledger items: %v\n", err)
        return
    }

for _, item := range result.LedgerItems {
        fmt.Printf("Amount: %.2f, Kind: %s, Date: %s\n", item.Amount, item.Kind, item.CreatedAt)
        if item.AccessPass != nil {
            fmt.Printf("  Access Pass: %s\n", item.AccessPass.ID)
            if item.AccessPass.PassTemplate != nil {
                fmt.Printf("  Card Template: %s\n", item.AccessPass.PassTemplate.ID)
            }
        }
    }
}
```

```csharp
using AccessGrid;
using System;
using System.Threading.Tasks;

public async Task GetLedgerItemsAsync()
{
    var accountId = Environment.GetEnvironmentVariable("ACCOUNT_ID");
    var secretKey = Environment.GetEnvironmentVariable("SECRET_KEY");

using var client = new AccessGridClient(accountId, secretKey);

var result = await client.Console.GetLedgerItemsAsync(
        startDate: DateTime.UtcNow.AddDays(-30),
        endDate: DateTime.UtcNow,
        page: 1,
        perPage: 50
    );

foreach (var item in result.LedgerItems)
    {
        Console.WriteLine($"Amount: {item.Amount}, Kind: {item.Kind}, Date: {item.CreatedAt}");
        if (item.AccessPass != null)
        {
            Console.WriteLine($"  Access Pass: {item.AccessPass.Id}");
            if (item.AccessPass.PassTemplate != null)
                Console.WriteLine($"  Card Template: {item.AccessPass.PassTemplate.Id}");
        }
    }
}
```

```java
import com.organization.accessgrid.AccessGridClient;
import com.organization.accessgrid.model.LedgerItem;
import com.organization.accessgrid.model.LedgerItemsParams;
import com.organization.accessgrid.model.LedgerItemsResult;
import java.time.ZonedDateTime;

public class BillingService {
    private final AccessGridClient client;

public BillingService() {
        String accountId = System.getenv("ACCOUNT_ID");
        String secretKey = System.getenv("SECRET_KEY");
        this.client = new AccessGridClient(accountId, secretKey);
    }

public void getLedgerItems() throws AccessGridException {
        LedgerItemsParams params = LedgerItemsParams.builder()
            .page(1)
            .perPage(50)
            .startDate(ZonedDateTime.now().minusDays(30))
            .endDate(ZonedDateTime.now())
            .build();

LedgerItemsResult result = client.console().ledgerItems(params);

for (LedgerItem item : result.getLedgerItems()) {
            System.out.printf("Amount: %s, Kind: %s, Date: %s%n",
                item.getAmount(),
                item.getKind(),
                item.getCreatedAt());
            if (item.getAccessPass() != null) {
                System.out.printf("  Access Pass: %s%n", item.getAccessPass().getExId());
                if (item.getAccessPass().getPassTemplate() != null)
                    System.out.printf("  Card Template: %s%n", item.getAccessPass().getPassTemplate().getExId());
            }
        }
    }
}
```

```php
<?php

require 'vendor/autoload.php';

use AccessGrid\Client;

$accountId = $_ENV['ACCOUNT_ID'];
$secretKey = $_ENV['SECRET_KEY'];

$client = new Client($accountId, $secretKey);

$result = $client->console->ledgerItems([
    'page' => 1,
    'per_page' => 50,
    'start_date' => (new DateTime('30 days ago'))->format('c'),
    'end_date' => (new DateTime('now'))->format('c')
]);

foreach ($result['ledger_items'] as $item) {
    echo "Amount: {$item['amount']}, Kind: {$item['kind']}, Date: {$item['created_at']}\n";
    if ($item['access_pass']) {
        echo "  Access Pass: {$item['access_pass']['ex_id']}\n";
        if ($item['access_pass']['pass_template']) {
            echo "  Card Template: {$item['access_pass']['pass_template']['ex_id']}\n";
        }
    }
}
```

```elixir
{:ok, client} = AccessGrid.new(
  System.get_env("ACCOUNT_ID"),
  System.get_env("SECRET_KEY")
)

{:ok, items} = AccessGrid.Console.ledger_items(client,
  page: 1,
  per_page: 50,
  start_date: DateTime.utc_now() |> DateTime.add(-30, :day) |> DateTime.to_iso8601(),
  end_date: DateTime.utc_now() |> DateTime.to_iso8601()
)

Enum.each(items, fn item ->
  IO.puts("Amount: #{item.amount}, Kind: #{item.kind}, Date: #{item.created_at}")
  if item.access_pass do
    IO.puts("  Access Pass: #{item.access_pass.ex_id}")
    if item.access_pass.pass_template do
      IO.puts("  Card Template: #{item.access_pass.pass_template.ex_id}")
    end
  end
end)
```

### Response

```json
{
    "ledger_items": [
        {
            "created_at": "2025-12-15T14:30:00Z",
            "amount": "1.50",
            "id": "li_9f3a12bc",
            "kind": "debit",
            "metadata": {
                "access_pass_id": "ap_a91c7e23",
                "pass_template_id": "0xd3adb00b5",
                "template_name": "Corporate Access Badge"
            },
            "access_pass": {
                "id": "ap_a91c7e23",
                "full_name": "John Doe",
                "state": "active",
                "metadata": {
                    "employee_id": "EMP-001"
                },
                "pass_template": {
                    "id": "0xd3adb00b5",
                    "name": "Corporate Access Badge",
                    "protocol": "desfire",
                    "platform": "apple",
                    "use_case": "corporate_id"
                },
                "unified_access_pass_id": "uap_b81d77ef"
            }
        },
        {
            "created_at": "2025-12-14T09:15:00Z",
            "amount": "1.50",
            "id": "li_c83d19aa",
            "kind": "debit",
            "metadata": {
                "access_pass_id": "ap_d72f91bb",
                "pass_template_id": "0xd3adb00b5",
                "template_name": "Corporate Access Badge"
            },
            "access_pass": {
                "id": "ap_d72f91bb",
                "full_name": "Jane Smith",
                "state": "active",
                "metadata": {},
                "pass_template": {
                    "id": "0xd3adb00b5",
                    "name": "Corporate Access Badge",
                    "protocol": "desfire",
                    "platform": "apple",
                    "use_case": "corporate_id"
                }
            }
        }
    ],
    "pagination": {
        "current_page": 1,
        "per_page": 50,
        "total_pages": 1,
        "total_count": 2
    }
}
```
