parcelwing / parcelwing-php
Official PHP SDK for the Parcel Wing API.
v0.1.0
2026-05-10 17:24 UTC
Requires
- php: >=8.1
- ext-curl: *
- ext-json: *
Requires (Dev)
- phpunit/phpunit: ^10.5 || ^11.0
This package is not auto-updated.
Last update: 2026-05-11 19:08:57 UTC
README
Official PHP SDK for the Parcel Wing API.
composer require parcelwing/parcelwing-php
Send an email
<?php require __DIR__ . '/vendor/autoload.php'; use ParcelWing\ParcelWing; use ParcelWing\Exceptions\ParcelWingException; $parcelwing = new ParcelWing($_ENV['PARCELWING_API_KEY']); try { $emails = $parcelwing->emails->send([ 'from' => 'Acme <onboarding@example.com>', 'to' => 'delivered@example.com', 'subject' => 'Hello from Parcel Wing', 'html' => '<strong>It works!</strong>', ]); print_r($emails); } catch (ParcelWingException $error) { echo $error->getMessage() . PHP_EOL; }
emails->send() returns an array of queued email objects. If to contains multiple recipients, Parcel Wing queues one email per recipient.
Client options
$parcelwing = new ParcelWing( apiKey: $_ENV['PARCELWING_API_KEY'], baseUrl: 'https://parcelwing.com', timeoutMs: 30000, headers: [ 'X-Request-Source' => 'my-app', ], );
baseUrl is useful for local testing or preview deployments.
Email API
$parcelwing->emails->send([ 'from' => 'Sender <sender@example.com>', 'to' => ['alice@example.com', 'bob@example.com'], 'subject' => 'Quarterly update', 'text' => 'Plain-text fallback', 'html' => '<p>HTML body</p>', 'reply_to' => 'support@example.com', 'tags' => [ 'campaign' => 'q1-update', ], ]);
Templates
Use either template_id or template_alias, not both.
$parcelwing->emails->send([ 'from' => 'Acme <onboarding@example.com>', 'to' => 'new-user@example.com', 'template_alias' => 'welcome', 'template_params' => [ 'first_name' => 'Ada', 'workspace_name' => 'Acme', ], ]);
Contacts
$contact = $parcelwing->contacts->create([ 'email' => 'ada@example.com', 'first_name' => 'Ada', 'last_name' => 'Lovelace', 'attributes' => [ 'plan' => 'flight', ], ]); $contacts = $parcelwing->contacts->list([ 'limit' => 25, 'status' => 'active', ]); $updated = $parcelwing->contacts->update($contact['id'], [ 'first_name' => 'Augusta Ada', ]); $parcelwing->contacts->delete($contact['id']);
Batch create contacts by passing an array of contact payloads:
$result = $parcelwing->contacts->create([ ['email' => 'alice@example.com'], ['email' => 'bob@example.com'], ]);
Segments
$segment = $parcelwing->segments->create([ 'name' => 'Flight customers', 'filter_criteria' => [ 'version' => 1, 'match' => 'all', 'conditions' => [[ 'field' => 'attribute', 'attribute_key' => 'plan', 'operator' => 'equals', 'value' => 'flight', ]], ], ]); $segments = $parcelwing->segments->list(['include_counts' => true]);
Topics
$topic = $parcelwing->topics->create([ 'name' => 'Product updates', 'description' => 'News and product announcements.', 'default_subscription' => 'opt_out', 'visibility' => 'public', ]);
Automations
$event = $parcelwing->automations->track([ 'event_name' => 'user.signup', 'contact_id' => 'contact_id_here', 'payload' => [ 'plan' => 'launch', ], ]);
Error handling
Failed API calls throw ParcelWing\Exceptions\ParcelWingException.
try { $parcelwing->emails->send([ 'from' => 'bad', 'to' => 'not-an-email', ]); } catch (ParcelWingException $error) { echo $error->status; // HTTP status, or 0 for network errors echo $error->type; // validation_error, authentication_error, api_error, etc. echo $error->errorCode ?? ''; // Parcel Wing error code when available print_r($error->details); }
Development
composer install
composer lint
composer test
License
MIT