PHPackages                             cardtechie/tradingcardapi-sdk-php - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [API Development](/categories/api)
4. /
5. cardtechie/tradingcardapi-sdk-php

ActiveLibrary[API Development](/categories/api)

cardtechie/tradingcardapi-sdk-php
=================================

Official PHP SDK for Trading Card API - comprehensive tools for accessing trading card data, players, sets, and market information with enhanced error handling and Laravel integration

0.2.26(3d ago)1175[31 issues](https://github.com/cardtechie/tradingcardapi-sdk-php/issues)MITPHPPHP ^8.2CI passing

Since May 27Pushed 3w agoCompare

[ Source](https://github.com/cardtechie/tradingcardapi-sdk-php)[ Packagist](https://packagist.org/packages/cardtechie/tradingcardapi-sdk-php)[ Docs](https://github.com/cardtechie/tradingcardapi-sdk-php)[ RSS](/packages/cardtechie-tradingcardapi-sdk-php/feed)WikiDiscussions main Synced today

READMEChangelog (10)Dependencies (56)Versions (57)Used By (0)

Trading Card API SDK for PHP
============================

[](#trading-card-api-sdk-for-php)

[![Latest Version on Packagist](https://camo.githubusercontent.com/408701e017bca0f05251a62cb6b1a6309b7832fbc892423daa4ea84a1c4f0e86/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f636172647465636869652f74726164696e67636172646170692d73646b2d7068702e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/cardtechie/tradingcardapi-sdk-php)[![GitHub Tests](https://camo.githubusercontent.com/b072f37fdfa09037f66560aecb4f9cc7950c920c5d4ecdf4885e67b4c7879c95/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f636172647465636869652f74726164696e67636172646170692d73646b2d7068702f636f64652d7175616c6974792e796d6c3f6272616e63683d6d61696e266c6162656c3d7465737473267374796c653d666c61742d737175617265)](https://github.com/cardtechie/tradingcardapi-sdk-php/actions?query=workflow%3Acode-quality+branch%3Amain)[![Total Downloads](https://camo.githubusercontent.com/c2252d8aac45c2d8096048093697d487c0d28eab7ff2baf0ad64d1c76c2f3185/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f636172647465636869652f74726164696e67636172646170692d73646b2d7068702e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/cardtechie/tradingcardapi-sdk-php)[![License: MIT](https://camo.githubusercontent.com/f10ea8ecf1433adae6d37d26d5545dd9262cf4b147a8b51e7157260ee03afbe8/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f636172647465636869652f74726164696e67636172646170692d73646b2d7068702e7376673f7374796c653d666c61742d737175617265)](LICENSE.md)

A modern PHP SDK for integrating with the Trading Card API. This Laravel package provides a clean, type-safe interface for accessing trading card data including cards, sets, players, teams, and more.

✨ Features
----------

[](#-features)

- 🔧 **Laravel Integration** - Built specifically for Laravel applications
- 🛡️ **Type Safety** - Full PHPStan Level 4 compliance with strict typing
- 🧪 **Well Tested** - Comprehensive test suite (Pest) covering the SDK's public surface
- 📦 **Easy Installation** - Simple Composer installation and configuration
- 🔄 **OAuth2 Authentication** - Automatic token management and renewal
- 🚨 **Enhanced Error Handling** - Specific exception classes for different error types
- 📖 **Rich Documentation** - Clear examples and comprehensive API coverage
- ⚡ **Built on Guzzle** - HTTP transport via the battle-tested GuzzleHTTP client

📋 Requirements
--------------

[](#-requirements)

- PHP 8.2 or higher
- Laravel 10.0 or higher
- GuzzleHTTP 7.5 or higher

🚀 Installation
--------------

[](#-installation)

Install the package via Composer:

```
composer require cardtechie/tradingcardapi-sdk-php
```

Publish the configuration file:

```
php artisan vendor:publish --tag="tradingcardapi-config"
```

Add your API credentials to your `.env` file:

```
TRADINGCARDAPI_URL=https://api.tradingcardapi.com
TRADINGCARDAPI_CLIENT_ID=your_client_id
TRADINGCARDAPI_CLIENT_SECRET=your_client_secret
TRADINGCARDAPI_SSL_VERIFY=true

# HTTP timeouts (seconds) — defaults shown; 0 disables a timeout
TRADINGCARDAPI_TIMEOUT=10
TRADINGCARDAPI_CONNECT_TIMEOUT=5

# Opt-in retry/backoff for 429 and 5xx responses (and connection errors)
TRADINGCARDAPI_RETRY_ENABLED=false
TRADINGCARDAPI_RETRY_MAX_ATTEMPTS=3
TRADINGCARDAPI_RETRY_BASE_DELAY_MS=1000
```

🎯 Quick Start
-------------

[](#-quick-start)

### Using the Facade

[](#using-the-facade)

```
use CardTechie\TradingCardApiSdk\Facades\TradingCardApiSdk;

// Get a specific card
$card = TradingCardApiSdk::card()->get('card-id');

// Search for cards
$cards = TradingCardApiSdk::card()->list(['name' => 'Pikachu']);

// Get player information
$player = TradingCardApiSdk::player()->get('player-id');

// Get paginated list of players
$players = TradingCardApiSdk::player()->list(['limit' => 25, 'page' => 1]);

// Search for players (returns Collection)
$players = TradingCardApiSdk::player()->all(['full_name' => 'Michael Jordan']);
```

### Using the Helper Function

[](#using-the-helper-function)

```
// Get a set with related data
$set = tradingcardapi()->set()->get('set-id', ['include' => 'cards,genre']);

// Create a new team
$team = tradingcardapi()->team()->create([
    'name' => 'New Team',
    'location' => 'City Name'
]);
```

### Error Handling

[](#error-handling)

The SDK provides comprehensive error handling with specific exception classes:

```
use CardTechie\TradingCardApiSdk\Exceptions\{
    CardNotFoundException,
    ConflictException,
    ValidationException,
    RateLimitException,
    AuthenticationException
};

try {
    $card = TradingCardApiSdk::card()->get('invalid-id');
} catch (CardNotFoundException $e) {
    // Handle missing card
    echo "Card not found: " . $e->getMessage();
} catch (ConflictException $e) {
    // Handle duplicate resource (HTTP 409)
    echo "Conflict: " . $e->getMessage();
} catch (ValidationException $e) {
    // Handle validation errors
    foreach ($e->getValidationErrors() as $field => $errors) {
        echo "Field $field: " . implode(', ', $errors);
    }
} catch (RateLimitException $e) {
    // Handle rate limiting
    echo "Rate limited. Retry after: " . $e->getRetryAfter() . " seconds";
}
```

### Direct Class Usage

[](#direct-class-usage)

```
use CardTechie\TradingCardApiSdk\TradingCardApi;

$api = new TradingCardApi();
$genres = $api->genre()->list();
```

### Meta and links

[](#meta-and-links)

Top-level JSON:API `meta` and `links` are **document-scoped** — they describe the whole response (pagination totals, `self`/`next`/`prev` links). The SDK attaches them to the **main parsed object only**, and you read them with `getMeta()` / `getLinks()`:

```
$cards = TradingCardApi::card()->list();

$cards->getMeta()->total;        // e.g. 1500
$cards->getLinks()->next;        // e.g. https://api.example.com/cards?page=2
```

Included relationship models do **not** carry the top-level meta/links — calling `getMeta()` / `getLinks()` on an included model returns an empty `stdClass` by design. Document-scoped links describe the main collection, so copying them onto an included resource (e.g. a sideloaded `Player`) would be misleading.

```
$player = $cards->getRelationships()['players'][0];
(array) $player->getMeta();       // []  — empty by design
```

👥 Working with Players
----------------------

[](#-working-with-players)

The Player resource provides comprehensive CRUD operations and relationship management:

### Basic Operations

[](#basic-operations)

```
use CardTechie\TradingCardApiSdk\Facades\TradingCardApiSdk;

// Get a specific player
$player = TradingCardApiSdk::player()->get('player-id');

// Create a new player
$player = TradingCardApiSdk::player()->create([
    'first_name' => 'Michael',
    'last_name' => 'Jordan'
]);

// Update player information
$player = TradingCardApiSdk::player()->update('player-id', [
    'first_name' => 'Michael Jeffrey',
    'last_name' => 'Jordan'
]);

// Delete a player
TradingCardApiSdk::player()->delete('player-id');
```

### Listing and Searching

[](#listing-and-searching)

```
// Get paginated list of players
$players = TradingCardApiSdk::player()->list([
    'limit' => 50,
    'page' => 1,
    'sort' => 'last_name'
]);

// Search for players (returns Collection)
$players = TradingCardApiSdk::player()->all([
    'full_name' => 'Michael Jordan',
    'parent_id' => null  // Only parent players, not aliases
]);

// Find players by partial name
$players = TradingCardApiSdk::player()->all([
    'first_name' => 'Michael'
]);
```

### Player Relationships

[](#player-relationships)

```
// Working with player relationships
$player = TradingCardApiSdk::player()->get('player-id');

// Get parent player (if this is an alias)
$parent = $player->getParent();

// Get all aliases of this player
$aliases = $player->getAliases();

// Get teams this player has been associated with
$teams = $player->getTeams();

// Get all player-team relationships
$playerteams = $player->getPlayerteams();

// Check if player is an alias
if ($player->isAlias()) {
    echo "This is an alias of: " . $player->getParent()->full_name;
}

// Check if player has aliases
if ($player->hasAliases()) {
    echo "This player has " . $player->getAliases()->count() . " aliases";
}
```

### Creating Player Hierarchies

[](#creating-player-hierarchies)

```
// Create a parent player
$parent = TradingCardApiSdk::player()->create([
    'first_name' => 'Michael',
    'last_name' => 'Jordan'
]);

// Create an alias player with parent relationship
$alias = TradingCardApiSdk::player()->create(
    ['first_name' => 'Mike', 'last_name' => 'Jordan'],
    ['parent' => ['data' => ['type' => 'players', 'id' => $parent->id]]]
);
```

### Working with Deleted Players

[](#working-with-deleted-players)

```
// List deleted players
$deletedPlayers = TradingCardApiSdk::player()->listDeleted();

// Get a specific deleted player
$deletedPlayer = TradingCardApiSdk::player()->deleted('player-id');
```

### Player Model Attributes

[](#player-model-attributes)

```
$player = TradingCardApiSdk::player()->get('player-id');

// Access player data
echo $player->first_name;        // "Michael"
echo $player->last_name;         // "Jordan"
echo $player->full_name;         // "Michael Jordan" (computed attribute)
echo $player->last_name_first;   // "Jordan, Michael" (computed attribute)

// Check relationships
echo $player->parent_id;         // UUID of parent player (if alias)
```

📚 Available Resources
---------------------

[](#-available-resources)

The SDK provides access to the following Trading Card API resources:

ResourceDescriptionMethods**Cards**Individual trading cards`get()`, `create()`, `update()`, `delete()`**Sets**Card sets and collections`get()`, `list()`, `create()`, `update()`, `delete()`, `checklist($id)`, `workflow($id)`, `addMissingCards($id)`, `addChecklist($request, $id)`**Players**Player information`get()`, `list()`, `all()`, `getList()` *(deprecated — use `all()`)*, `create()`, `update()`, `delete()`, `listDeleted()`, `deleted($id)`**Teams**Team data`get()`, `list()`, `all()`, `getList()` *(deprecated — use `all()`)*, `create()`, `update()`, `delete()`, `listDeleted()`, `deleted($id)`**Genres**Card categories/types`get()`, `list()`, `create()`, `update()`, `delete()`, `listDeleted()`, `deleted($id)`**Brands**Trading card brands`get()`, `list()`, `create()`, `update()`, `delete()`**Manufacturers**Trading card manufacturers`get()`, `list()`, `create()`, `update()`, `delete()`**Years**Trading card years`get()`, `list()`, `create()`, `update()`, `delete()`**ObjectAttributes**Object attributes`get()`, `list()`, `create()`, `update()`, `delete()`**SetSources**Set data sources`get()`, `list()`, `create()`, `update()`, `delete()`, `forSet($setId)`**Stats**Entity statistics and analytics`get($type)`, `getCounts()`, `getSnapshots()`, `getGrowth()`**Attributes**Card attributes`get()`, `list()`, `all()`, `create()`, `update()`, `delete()`**CardImages**Card image upload and management`list()`, `get($id)`, `upload($file, $cardId, $imageType)`, `update($id, $attributes)`, `delete($id)`, `getDownloadUrl($id, $size)`**Internal\\Workflow** *(internal only)*Set workflow management and bulk operations`actionableSets()`, `updateSetTodo($todoId, $attributes)`, `bulkInitializeWorkflow()`, `getBulkInitializeStatus($jobId)`, `getSetTodos($setId)`, `getReviewQueue($step?, $params?)`, `flagForReview($todoId, $reason)`, `resolveReview($todoId, $notes?)`**Internal\\AuditLog** *(internal only)*Audit log tracking and creation`getAuditLogs($params?)`, `createAuditEvent($attributes?)`### Stats Resource

[](#stats-resource)

The Stats resource provides analytics and tracking capabilities for entity counts:

```
// Get current counts for all entity types
$counts = $api->stats()->getCounts();

// Access counts for a specific entity type
$setsCount = $counts->getByEntityType('sets');
echo $setsCount->total;      // Total count
echo $setsCount->published;  // Published count
echo $setsCount->draft;      // Draft count
echo $setsCount->archived;   // Archived count

// Get growth metrics (default: 7 days)
$growth = $api->stats()->getGrowth();
// Or specify a period: '7d', '30d', '90d', 'week', 'month'
$growth = $api->stats()->getGrowth('30d');

$setsGrowth = $growth->getByEntityType('sets');
echo $setsGrowth->current;          // Current count
echo $setsGrowth->previous;         // Previous period count
echo $setsGrowth->change;           // Absolute change
echo $setsGrowth->percentageChange; // Percentage change

// Get historical snapshots
$snapshots = $api->stats()->getSnapshots();

// With filters
$snapshots = $api->stats()->getSnapshots([
    'entity_type' => 'sets',
    'from' => '2024-11-01',
    'to' => '2024-11-30',
]);

foreach ($snapshots->snapshots as $snapshot) {
    echo $snapshot->date;        // Snapshot date
    echo $snapshot->entityType;  // Entity type
    echo $snapshot->total;       // Total at that point
}
```

### SetSource Resource

[](#setsource-resource)

The SetSource resource manages data sources for trading card sets (checklists, metadata, images):

```
// Get all sources for a specific set
$sources = $api->setSource()->forSet('set-id');

// Get a specific source
$source = $api->setSource()->get('source-id');

// Create a new set source
$source = $api->setSource()->create([
    'set_id' => 'set-uuid',
    'source_url' => 'https://example.com/checklist',
    'source_name' => 'Example Source',
    'source_type' => 'checklist',  // checklist, metadata, or images
]);

// Update a source
$source = $api->setSource()->update('source-id', [
    'source_url' => 'https://example.com/updated-checklist',
    'verified_at' => '2024-01-15T10:30:00Z',
]);

// Delete a source
$api->setSource()->delete('source-id');

// Include sources when fetching a set
$set = $api->set()->get('set-id', ['include' => 'sources']);

// Returns an Illuminate\Support\Collection of SetSource models
$sources = $set->sources();

if ($sources->isEmpty()) {
    echo 'No sources found for this set.';
} else {
    $firstSource = $sources->first();
    echo $firstSource->source_name;
}
```

### Internal Namespace

[](#internal-namespace)

> **Internal use only — not part of the public API contract; may change without semver guarantees.**
>
> The `Internal\` namespace is intended for internal callers (admin tooling, tradingcardapi-mcp, tradingcardapi-tools). Credentials must carry the `internal` OAuth scope; calls will fail with a 403 if this scope is absent.

Access the internal client via `$api->internal()`:

```
$internal = $api->internal();

// workflow and audit-log resources are now under internal()
$actionable = $internal->workflow()->actionableSets();
$logs       = $internal->auditLog()->getAuditLogs();
```

#### Internal\\Workflow Resource

[](#internalworkflow-resource)

The internal Workflow resource manages set workflow steps (todos) and bulk initialization via `/internal/*` routes:

```
$workflow = $api->internal()->workflow();

// Get sets that have actionable workflow steps
// Returns a typed ActionableSetsResponse (->sets is an array of ActionableSet)
$actionable = $workflow->actionableSets();
foreach ($actionable->sets as $set) {
    echo $set->attributes->name;
}

// Filter actionable sets
$actionable = $workflow->actionableSets(['filter[sport]' => 'baseball']);

// Get workflow status for a specific set (via Set resource — still public)
$workflowStatus = $api->set()->workflow('set-id');

// Update a workflow step (set-todo) status
$result = $workflow->updateSetTodo('todo-id', [
    'status' => 'completed',
]);

// Bulk initialize workflow todos for all existing sets
$job = $workflow->bulkInitializeWorkflow();
echo $job->data->job_id;   // Job ID to poll for status
echo $job->data->status;   // 'queued'

// Initialize workflow todos for specific sets only
$job = $workflow->bulkInitializeWorkflow([
    'set_ids' => ['set-id-1', 'set-id-2'],
]);

// Poll bulk initialization job status
$status = $workflow->getBulkInitializeStatus($job->data->job_id);
echo $status->data->status;     // 'queued', 'processing', or 'completed'
echo $status->data->processed;  // Sets processed so far
echo $status->data->total;      // Total sets to process

// Get workflow todos for a specific set
$result = $workflow->getSetTodos('set-id');
foreach ($result->todos as $todo) {
    echo $todo->step;    // e.g. 'discover_sources'
    echo $todo->status;  // e.g. 'completed'
}

// Get all sets blocked for human review
$reviewQueue = $workflow->getReviewQueue();

// Filter review queue by workflow step
$parseReview = $workflow->getReviewQueue('parse');

// Flag a workflow step for human review
$workflow->flagForReview('todo-id', 'Data quality issue detected');

// Resolve a review (resets to pending)
$workflow->resolveReview('todo-id');
$workflow->resolveReview('todo-id', 'Verified card data is correct');

// Use WorkflowStatus and WorkflowStep enums instead of magic strings
$workflow->updateSetTodo('todo-id', [
    'status' => \CardTechie\TradingCardApiSdk\Enums\WorkflowStatus::COMPLETED->value,
]);
```

#### Internal\\AuditLog Resource

[](#internalauditlog-resource)

The internal AuditLog resource provides access to audit logging endpoints via `/internal/*` routes:

```
$auditLog = $api->internal()->auditLog();

// Get audit logs with pagination
$logs = $auditLog->getAuditLogs();

// Filter audit logs
$logs = $auditLog->getAuditLogs([
    'auditable_type' => 'Set',
    'auditable_id' => 'set-uuid',
    'agent_id' => 'agent-uuid',
    'event_type' => 'created',
    'start_date' => '2026-01-01',
    'end_date' => '2026-04-13',
    'per_page' => 25,
    'page' => 1,
]);

// Create an audit event
$event = $auditLog->createAuditEvent([
    'auditable_type' => 'Set',
    'auditable_id' => 'set-uuid',
    'event_type' => 'manual_review',
    'description' => 'Manual review completed',
]);
```

### CardImage Resource

[](#cardimage-resource)

The CardImage resource handles card image uploads and management:

```
// Upload a card image
$image = $api->cardImage()->upload(
    $request->file('image'),  // UploadedFile or file path
    'card-id',
    'front'  // 'front' or 'back'
);

// Upload with additional attributes
$image = $api->cardImage()->upload(
    '/path/to/image.jpg',
    'card-id',
    'front',
    ['is_primary' => true]
);

// Get a card image
$image = $api->cardImage()->get('image-id');

// Get download URL
$url = $api->cardImage()->getDownloadUrl('image-id');           // original size
$url = $api->cardImage()->getDownloadUrl('image-id', 'small');  // small variant

// Update image metadata
$image = $api->cardImage()->update('image-id', ['is_primary' => true]);

// List card images with filtering
$images = $api->cardImage()->list(['filter[card_id]' => 'card-id']);

// Delete a card image
$api->cardImage()->delete('image-id');
```

🔧 Configuration
---------------

[](#-configuration)

The configuration file (`config/tradingcardapi.php`) supports:

```
return [
    'url' => env('TRADINGCARDAPI_URL', ''),
    'ssl_verify' => (bool) env('TRADINGCARDAPI_SSL_VERIFY', true),
    'client_id' => env('TRADINGCARDAPI_CLIENT_ID', ''),
    'client_secret' => env('TRADINGCARDAPI_CLIENT_SECRET', ''),
    'scope' => env('TRADINGCARDAPI_SCOPE', 'read:published'),
    'timeout' => (float) env('TRADINGCARDAPI_TIMEOUT', 10),
    'connect_timeout' => (float) env('TRADINGCARDAPI_CONNECT_TIMEOUT', 5),
    'retry' => [
        'enabled' => (bool) env('TRADINGCARDAPI_RETRY_ENABLED', false),
        'max_attempts' => (int) env('TRADINGCARDAPI_RETRY_MAX_ATTEMPTS', 3),
        'base_delay' => (int) env('TRADINGCARDAPI_RETRY_BASE_DELAY_MS', 1000),
    ],
];
```

### HTTP Timeouts

[](#http-timeouts)

By default the SDK applies a **10-second request timeout** and a **5-second connect timeout** to every request. Guzzle ships with no timeout at all, so without these a hung API would block the calling PHP-FPM worker indefinitely.

Env varDefaultMeaning`TRADINGCARDAPI_TIMEOUT``10`Total seconds to wait for a response. `0` disables.`TRADINGCARDAPI_CONNECT_TIMEOUT``5`Seconds to wait while establishing the connection. `0` disables.A connect timeout makes `NetworkException::connectionTimeout` reachable — it could never fire previously because no timeout was ever set.

### Retry / Backoff

[](#retry--backoff)

Retrying transient failures is **opt-in** (disabled by default to preserve existing behavior). When enabled, the SDK retries `429` and `5xx` responses and connection errors with exponential backoff (`base_delay * 2^(attempt-1)`ms). If a `429` carries a numeric `Retry-After` header, that value is honored in preference to the computed backoff.

Env varDefaultMeaning`TRADINGCARDAPI_RETRY_ENABLED``false`Enable automatic retries.`TRADINGCARDAPI_RETRY_MAX_ATTEMPTS``3`Max retries after the initial request.`TRADINGCARDAPI_RETRY_BASE_DELAY_MS``1000`Base backoff delay in milliseconds.### OAuth Scopes

[](#oauth-scopes)

Configure the OAuth scopes to request when authenticating. Available scopes:

- **`read:published`** (default) - Access published content only
- **`read:draft`** - Access published and draft content
- **`read:all-status`** - Access all content regardless of status
- **`write`** - Create and update resources
- **`delete`** - Delete resources

#### Examples

[](#examples)

**Read-only access to published content:**

```
TRADINGCARDAPI_SCOPE="read:published"
```

**Admin access with full permissions:**

```
TRADINGCARDAPI_SCOPE="read:all-status write delete"
```

**Content management (no delete):**

```
TRADINGCARDAPI_SCOPE="read:draft write"
```

Multiple scopes should be separated by spaces. If not specified, the default scope (`read:published`) is used.

🧪 Development &amp; Testing
---------------------------

[](#-development--testing)

This project uses modern PHP development tools and practices:

### Prerequisites

[](#prerequisites)

- Docker and Docker Compose
- Make (optional, for convenience commands)

### Getting Started

[](#getting-started)

```
# Clone the repository
git clone https://github.com/cardtechie/tradingcardapi-sdk-php.git
cd tradingcardapi-sdk-php

# Start development environment
make up

# Install dependencies
make install

# Run tests
make test

# Run code quality checks
make check
```

### Available Commands

[](#available-commands)

```
make test              # Run test suite
make analyse           # Run PHPStan static analysis
make format            # Format code with Laravel Pint
make check             # Run all quality checks
make quality           # Run comprehensive quality checks with coverage
make ci                # Run CI pipeline locally

# Release management commands
make version           # Show current version
make changelog-update  # Update changelog for current version
make release-notes-preview  # Generate release notes preview
```

### Code Quality Standards

[](#code-quality-standards)

This project maintains high code quality standards:

- ✅ **PHPStan Level 4** - Strict static analysis
- ✅ **PSR-12** - Code style compliance via Laravel Pint
- ✅ **Comprehensive Test Suite** - Extensive coverage using Pest (run `make test-coverage` for a local report)
- ✅ **Automated CI/CD** - Quality checks on all PRs

📖 Documentation
---------------

[](#-documentation)

- **[Error Handling Guide](docs/ERROR-HANDLING.md)** - Comprehensive guide to exception handling
- **[Response Validation](docs/VALIDATION.md)** - Response validation and schema handling
- **[Version Management](docs/VERSION-MANAGEMENT.md)** - Release process and versioning
- **[Trading Card API Documentation](https://docs.tradingcardapi.com)** - Complete API reference

### Upgrade Notes (0.3.0)

[](#upgrade-notes-030)

The 0.3.0 Resource-layer standardization introduces two consumer-visible changes:

- **`getList()` is deprecated in favor of `all()`** on the `Player`, `Team`, and `Playerteam` resources. `getList()` still works (it delegates to `all()` with identical behavior) but is marked `@deprecated`, so static analysis (e.g. PHPStan `method.deprecated`) will flag remaining call sites. Migrate `->getList(...)` to `->all(...)`.
- **`RateLimitException::__construct` positional slots were realigned** with the base `TradingCardApiException`: `$httpStatusCode` (default `429`) is now positional slot 6 and `$context` slot 7. Construct `RateLimitException` with **named arguments** to be safe against the slot change — see the [Error Handling Guide](docs/ERROR-HANDLING.md#ratelimitexception-429).

🤝 Contributing
--------------

[](#-contributing)

We welcome contributions! Open an issue or start a thread in [GitHub Discussions](https://github.com/cardtechie/tradingcardapi-sdk-php/discussions) before submitting a pull request. See [CONTRIBUTING.md](CONTRIBUTING.md) for the full contributor guide — development setup, coding standards, testing requirements, the changelog-fragment and pull-request process, and issue reporting.

### Development Workflow

[](#development-workflow)

1. Fork the repository
2. Create a feature branch
3. Make your changes
4. Run quality checks: `make check`
5. Submit a pull request

🐛 Bug Reports &amp; Feature Requests
------------------------------------

[](#-bug-reports--feature-requests)

Please use the [GitHub Issues](https://github.com/cardtechie/tradingcardapi-sdk-php/issues) to report bugs or request features.

🔒 Security
----------

[](#-security)

Please review our [Security Policy](../../security/policy) for reporting security vulnerabilities.

🚀 Release Process
-----------------

[](#-release-process)

This project uses a sophisticated, automated release management system adapted from the main Trading Card API repository.

### Version Management

[](#version-management)

The SDK uses intelligent, branch-aware semantic versioning:

- **Production releases** (`1.2.3`) - Created from `main` branch
- **Beta releases** (`1.3.0.beta-5`) - Created from `develop` branch
- **Release candidates** (`1.3.0.rc-2`) - Created from `release/*` branches
- **Development versions** (`1.2.3-alpha.4`) - Feature branches

### Development Commands

[](#development-commands)

```
# Check current version
make version

# Preview version for different branches
make version-preview --branch=main
make version-preview --branch=develop

# Update changelog for current version
make changelog-update

# Generate release notes preview
make release-notes-preview
```

### Automated Release Process

[](#automated-release-process)

1. **Development**: Features are developed on feature branches
2. **Integration**: Changes are merged to `develop` for testing
3. **Release Preparation**: Release branches are created for final testing
4. **Production Release**: Stable releases are merged to `main`
5. **Automation**: GitHub Actions handles versioning, changelog updates, and Packagist publishing

### Cutting a Release

[](#cutting-a-release)

Maintainers: see the **[Release Runbook](docs/RELEASING.md)** for the concrete, step-by-step procedure — how a release is cut, the required repository secrets, how to trigger a release manually via `workflow_dispatch`, how to verify the GitHub Release and Packagist update, and rollback notes.

See [docs/VERSION-MANAGEMENT.md](docs/VERSION-MANAGEMENT.md) for the underlying versioning model.

📄 Changelog
-----------

[](#-changelog)

See [CHANGELOG.md](CHANGELOG.md) for recent changes.

👥 Credits
---------

[](#-credits)

- [Josh Harrison](https://github.com/picklewagon) - Lead Developer
- [All Contributors](../../contributors)

📜 License
---------

[](#-license)

This project is licensed under the MIT License. See [LICENSE.md](LICENSE.md) for details.

---

Made with ❤️ by [CardTechie](https://github.com/cardtechie)

###  Health Score

39

—

LowBetter than 84% of packages

Maintenance71

Regular maintenance activity

Popularity16

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity51

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 84.2% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~6 days

Recently: every ~0 days

Total

44

Last Release

3d ago

PHP version history (2 changes)0.1.0PHP ^8.1

0.2.0PHP ^8.2

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/85095683?v=4)[CardTechie](/maintainers/cardtechie)[@cardtechie](https://github.com/cardtechie)

---

Top Contributors

[![picklewagon](https://avatars.githubusercontent.com/u/1139280?v=4)](https://github.com/picklewagon "picklewagon (240 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (26 commits)")[![github-actions[bot]](https://avatars.githubusercontent.com/in/15368?v=4)](https://github.com/github-actions[bot] "github-actions[bot] (19 commits)")

---

Tags

laravelsdkrestapi clientcardtechietradingcardapitrading-cardssports-cards

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/cardtechie-tradingcardapi-sdk-php/health.svg)

```
[![Health](https://phpackages.com/badges/cardtechie-tradingcardapi-sdk-php/health.svg)](https://phpackages.com/packages/cardtechie-tradingcardapi-sdk-php)
```

###  Alternatives

[dedoc/scramble

Automatic generation of API documentation for Laravel applications.

2.1k11.2M100](/packages/dedoc-scramble)[simplestats-io/laravel-client

Server-side analytics for Laravel that follows the full funnel from visit to registration to payment, attributed to the channel that drove it. Revenue, MRR, churn and ad-spend profit (ROAS/CAC) per channel. GDPR compliant, ad-blocker proof.

5021.9k](/packages/simplestats-io-laravel-client)[spatie/laravel-health

Monitor the health of a Laravel application

87512.0M165](/packages/spatie-laravel-health)[spatie/laravel-pdf

Create PDFs in Laravel apps

1.0k4.8M47](/packages/spatie-laravel-pdf)[defstudio/telegraph

A laravel facade to interact with Telegram Bots

816333.3k3](/packages/defstudio-telegraph)[nativephp/mobile

NativePHP for Mobile

1.1k75.1k91](/packages/nativephp-mobile)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
