A PHP library for connecting to Amazon's Selling Partner API.
Note
If you're looking for the documentation for v5 of this package, you can find it here.
highsidelabs/laravel-spapi
: A Laravel wrapper for this package that makes SP API integration in Laravel projects quick and easy.highsidelabs/amazon-business-api
: A PHP library for Amazon's Business API, with a near-identical interface to this package.highsidelabs/walmart-api
: A PHP library for Walmart's seller and supplier APIs, including the Marketplace, Drop Ship Vendor, Content Provider, and Warehouse Supplier APIs.
This package is developed and maintained by Highside Labs. If you need support integrating with Amazon's (or any other e-commerce platform's) APIs, we're happy to help! Shoot us an email at hi@highsidelabs.co. We'd love to hear from you :)
If you've found any of our packages useful, please consider becoming a Sponsor, or making a one-time donation via the button below. I appreciate any and all support you can provide!
Sponsored by Tesmo.
- Supports all Selling Partner API operations (for Sellers and Vendors) as of 2/10/2024
- Automatically generates Restricted Data Tokens for all calls that require them -- no extra calls to the Tokens API needed
- Includes a
Document
helper class for uploading and downloading feed/report documents
composer require jlevers/selling-partner-api
Check out the Getting Started section below for a quick overview.
This README is divided into several sections:
- Setup
- Debugging
- Supported API segments
- Restricted operations
- Uploading and downloading documents
- Naming conventions
- API versions
- Working with DTOs
To get started, you need an approved Selling Partner API developer account, and SP API application credentials, which you can get by creating a new SP API application in Seller Central.
The SellingPartnerApi
class acts as a factory to generate API connector instances. It takes a set of (optionally) named parameters. Its basic usage looks like this:
use SellingPartnerApi\SellingPartnerApi;
use SellingPartnerApi\Enums\Endpoint;
$connector = SellingPartnerApi::make(
clientId: 'amzn1.application-oa2-client.asdfqwertyuiop...',
clientSecret: 'amzn1.oa2-cs.v1.1234567890asdfghjkl...',
refreshToken: 'Atzr|IwEBIA...',
endpoint: Endpoint::NA, // Or Endpoint::EU, Endpoint::FE, Endpoint::NA_SANDBOX, etc.
)->seller();
Note
Older versions of the Selling Partner API used AWS IAM credentials to authenticate, and so this library had additional AWS configuration options. If you're upgrading from an older version of this library and are confused about what to do with your AWS creds, you can just ignore them. The SP API no longer authenticates via AWS IAM roles or users.
Now you have a Selling Partner API connector instance, and you can start making calls to the API. The connector instance has methods for each of the API segments (e.g., sellers
, orders
, fba-inbound
), and you can access them like so:
$ordersApi = $connector->orders();
$response = $ordersApi->getOrders(
createdAfter: new DateTime('2024-01-01'),
marketplaceIds: ['ATVPDKIKX0DER'],
);
Once you have a response, you can either access the raw JSON response via $response->json()
, or you can automatically parse the response into a DTO by calling $response->dto()
. Once the response is turned into a DTO, you can access the data via the DTO's properties. For instance, you can get the first order's purchase date like so:
$dto = $response->dto();
$purchaseDate = $dto->payload->orders[0]->purchaseDate;
See the Working with DTOs section for more details on how to work with requests and responses.
The SellingPartnerApi::make()
builder method accepts the following keys:
clientId (string)
: Required. The LWA client ID of the SP API application to use to execute API requests.clientSecret (string)
: Required. The LWA client secret of the SP API application to use to execute API requests.refreshToken (string)
: The LWA refresh token of the SP API application to use to execute API requests. Required, unless you're only using grantless operations.endpoint
: Required. An instance of theSellingPartnerApi\Enums\Endpoint
enum. Primary endpoints areEndpoint::NA
,Endpoint::EU
, andEndpoint::FE
. Sandbox endpoints areEndpoint::NA_SANDBOX
,Endpoint::EU_SANDBOX
, andEndpoint::FE_SANDBOX
.dataElements (array)
: Optional. An array of data elements to pass to restricted operations. See the Restricted operations section for more details.delegatee (string)
: Optional. The application ID of a delegatee application to generate RDTs on behalf of.authenticationClient
: OptionalGuzzleHttp\ClientInterface
object that will be used to generate the access token from the refresh token. If not provided, a default Guzzle client will be used.
To get detailed debugging output, you can take advantage of Saloon's debugging hooks. This package is built on top of Saloon, so anything that works in Saloon will work here. For instance, to debug requests:
use SellingPartnerApi\SellingPartnerApi;
$connector = SellingPartnerApi::make(
clientId: 'amzn1.application-oa2-client.asdfqwertyuiop...',
clientSecret: 'amzn1.oa2-cs.v1.1234567890asdfghjkl...',
refreshToken: 'Atzr|IwEBIA...',
endpoint: Endpoint::NA,
)->seller();
$connector->debugRequest(
function (PendingRequest $pendingRequest, RequestInterface $psrRequest) {
dd($pendingRequest->headers()->all(), $psrRequest);
}
);
Then make requests with the connector as usual, and you'll hit the closure above every time a request is fired. You can also debug responses in a similar fashion – check out the Saloon docs for more details.
Each API class name contains the API's version. This allows for multiple versions of the same API to be accessible in a single version of this package. It makes the class names a little uglier, but allows for simultaneously using new and old versions of the same API segment, which is often useful. The uglier names can be remedied by formatting use
statements like so:
use SellingPartnerApi\Api\SellersV1Api as SellersApi;
use SellingPartnerApi\Model\SellersV1 as Sellers;
It also means that if a new version of an existing API is introduced, the library can be updated to include that new version without introducing breaking changes.
Seller APIs are accessed via the SellerConnector
class:
<?php
use SellingPartnerApi\SellingPartnerApi;
$sellerConnector = SellingPartnerApi::make(/* ... */)->seller();
- Application Management API (v2023-11-30) (docs)
$applicationManagementApi = $sellerConnector->applicationManagement();
- A+ Content API (v2020-11-01) (docs)
$aPlusContentApi = $sellerConnector->aPlusContent();
- Authorization API (v1) (docs)
$authorizationApi = $sellerConnector->authorization();
- Catalog Items API (v2022-04-01) (docs)
$catalogItemsApi = $sellerConnector->catalogItems();
- Catalog Items API (v2021-12-01) (docs)
$catalogItemsApi = $sellerConnector->catalogItemsV20211201();
- Catalog Items API (v0) (docs)
$catalogItemsApi = $sellerConnector->catalogItemsV0();
- Data Kiosk API (v2023-11-15) (docs)
$dataKioskApi = $sellerConnector->dataKiosk();
- EasyShip API (v2022-03-23) (docs)
$easyShipApi = $sellerConnector->easyShip();
- FBA Inbound API (v0) (docs)
$fbaInboundApi = $sellerConnector->fbaInbound();
- FBA Inbound Eligibility API (v1) (docs)
$fbaInboundEligibility = $sellerConnector->fbaInboundEligibility();
- FBA Inventory API (v1) (docs)
$fbaInventoryApi = $sellerConnector->fbaInventory();
- FBA Outbound API (v2020-07-01) (docs)
$fbaOutboundApi = $sellerConnector->fbaOutbound();
- FBA Small and Light API (v1) (docs)
$fbaSmallAndLightApi = $sellerConnector->fbaSmallAndLight();
- Feeds API (v2021-06-30) (docs)
$feedsApi = $sellerConnector->feeds();
- Finances API (v0) (docs)
$financesApi = $sellerConnector->finances();
- Listings Items API (v2021-08-01) (docs)
$listingsItemsApi = $sellerConnector->listingsItems();
- Listings Items API (v2020-09-01) (docs)
$listingsItemsApi = $sellerConnector->listingsItemsV20200901();
- Listings Restrictions API (v2021-08-01) (docs)
$listingsRestrictionsApi = $sellerConnector->listingsRestrictions();
- Merchant Fulfillment API (v0) (docs)
$merchantFulfillmentApi = $sellerConnector->merchantFulfillment();
- Messaging API (v1) (docs)
$messagingApi = $sellerConnector->messaging();
- Notifications API (v1) (docs)
$notificationsApi = $sellerConnector->notifications();
- Orders API (v0) (docs)
$ordersApi = $sellerConnector->orders();
- Product Fees API (v0) (docs)
$productFeesApi = $sellerConnector->productFees();
- Product Pricing API (v2022-05-01) (docs)
$productPricingApi = $sellerConnector->productPricing();
- Product Pricing API (v0) (docs)
$productPricingApi = $sellerConnector->productPricingV0();
- Product Type Definitions API (v2020-09-01) (docs)
$productTypeDefinitionsApi = $sellerConnector->productTypeDefinitions();
- Replenishment API (v2022-11-07) (docs)
$replenishmentApi = $sellerConnector->replenishment();
- Reports API (v2021-06-30) (docs)
$reportsApi = $sellerConnector->reports();
- Sales API (v1) (docs)
$salesApi = $sellerConnector->sales();
- Sellers API (v1) (docs)
$sellersApi = $sellerConnector->sellers();
- Services API (v1) (docs)
$servicesApi = $sellerConnector->services();
- Shipment Invoicing API (v0) (docs)
$shipmentInvoicingApi = $sellerConnector->shipmentInvoicing();
- Shipping API (v2) (docs)
$shippingApi = $sellerConnector->shipping();
- Shipping API (v1) (docs)
$shippingApi = $sellerConnector->shippingV1();
- Solicitations API (v1) (docs)
$solicitationsApi = $sellerConnector->solicitations();
- Supply Sources API (v2020-07-01) (docs)
$supplySourcesApi = $sellerConnector->supplySources();
- Tokens API (v2021-03-01) (docs)
$tokensApi = $sellerConnector->tokens();
- Uploads API (v2020-11-01) (docs)
$uploadsApi = $sellerConnector->uploads();
Vendor APIs are accessed via the VendorConnector
class:
<?php
use SellingPartnerApi\SellingPartnerApi;
$vendorConnector = SellingPartnerApi::make(/* ... */)->vendor();
- Direct Fulfillment Inventory API (v1) (docs)
$directFulfillmentInventoryApi = $vendorConnector->directFulfillmentInventory();
- Direct Fulfillment Orders API (v2021-12-28) (docs)
$directFulfillmentOrdersApi = $vendorConnector->directFulfillmentOrders();
- Direct Fulfillment Orders API (v1) (docs)
$directFulfillmentOrdersApi = $vendorConnector->directFulfillmentOrdersV1();
- Direct Fulfillment Payments API (v1) (docs)
$directFulfillmentPaymentsApi = $vendorConnector->directFulfillmentPayments();
- Direct Fulfillment Sandbox API (v2021-10-28) (docs)
$directFulfillmentSandboxApi = $vendorConnector->directFulfillmentSandbox();
- Direct Fulfillment Shipping API (v2021-12-28) (docs)
$directFulfillmentShippingApi = $vendorConnector->directFulfillmentShipping();
- Direct Fulfillment Shipping API (v1) (docs)
$directFulfillmentShippingApi = $vendorConnector->directFulfillmentShippingV1();
- Direct Fulfillment Transactions API (v2021-12-28) (docs)
$directFulfillmentTransactionsApi = $vendorConnector->directFulfillmentTransactions();
- Direct Fulfillment Transactions API (v1) (docs)
$directFulfillmentTransactionsApi = $vendorConnector->directFulfillmentTransactionsV1();
- Invoices API (v1) (docs)
$invoicesApi = $vendorConnector->invoices();
- Orders API (v1) (docs)
$ordersApi = $vendorConnector->orders();
- Shipments API (v1) (docs)
$shipmentsApi = $vendorConnector->shipments();
- Transaction Status API (v1) (docs)
$transactionStatusApi = $vendorConnector->transactionStatus();
When you call a restricted operation, a Restricted Data Token (RDT) is automatically generated. If you're calling restricted operations that accept a dataElements
parameter, specify the restricted data elements you want to retrieve in the dataElements
parameter of SellingPartnerApi::make()
. Currently, getOrder
, getOrders
, and getOrderItems
are the only restricted operations that take a dataElements
parameter.
Note that if you want to call a restricted operation on a sandbox endpoint (e.g., Endpoint::NA_SANDBOX
), you should not specify any dataElements
. RDTs are not necessary for restricted operations in the sandbox.
If you would like to make calls on behalf of a delegatee application, you can specify the delegatee
parameter in SellingPartnerApi::make()
. This will cause the connector to generate a token for the delegatee application instead of the main application.
The Feeds and Reports APIs include operations that involve uploading and downloading documents to and from Amazon. This library has integrated supports for uploading and downloading documents on the relevant DTOs: ReportDocument
, CreateFeedDocumentResponse
, and FeedDocument
, which are the result of calling getReportDocument
, createFeedDocument
, and getFeedDocument
, respectively.
use SellingPartnerApi\SellingPartnerApi;
$reportType = 'GET_MERCHANT_LISTINGS_DATA';
// Assume we already got a report document ID from a previous getReport call
$documentId = '1234567890.asdf';
$connector = SellingPartnerApi::make(/* ... */)->seller();
$response = $connector->reports()->getReportDocument($documentId, $reportType);
$reportDocument = $response->dto();
/*
* - Array of arrays, where each sub array corresponds to a row of the report, if this is a TSV, CSV, or XLSX report
* - A nested associative array (from json_decode) if this is a JSON report
* - The raw report data if this is a TXT or PDF report
* - A SimpleXMLElement object if this is an XML report
*/
$contents = $reportDocument->download($reportType);
The download
method has three parameters:
documentType
(string): The report type (or feed type of the feed result document being fetched). This is required if you want the document data parsed for you.preProcess
(bool): Whether to preprocess the document data. Iftrue
, the document data will be parsed and formatted into a more usable format. Iffalse
, the raw document text will be returned. Defaults totrue
.encoding
(string): The encoding of the document data. Defaults toUTF-8
.
If you are working with huge documents you can use downloadStream()
to minimize the memory consumption. downloadStream()
returns a Psr\Http\Message\StreamInterface
.
$streamContents = $reportDocument->downloadStream(); // The raw report stream
use SellingPartnerApi\Seller\FeedsV20210630\Dto\CreateFeedDocumentSpecification;
use SellingPartnerApi\Seller\FeedsV20210630\Dto\CreateFeedSpecification;
use SellingPartnerApi\Seller\FeedsV20210630\Responses\CreateFeedDocumentResponse;
$feedType = 'POST_PRODUCT_PRICING_DATA';
$connector = SellingPartnerApi::make(/* ... */)->seller();
$feedsApi = $connector->feeds();
// Create feed document
$contentType = CreateFeedDocumentResponse::getContentType($feedType);
$createFeedDoc = new CreateFeedDocumentSpecification($contentType);
$createDocumentResponse = $feedsApi->createFeedDocument($createFeedDoc);
$feedDocument = $createDocumentResponse->dto();
// Upload feed contents to document
$feedContents = file_get_contents('your/feed/file.xml');
$feedDocument->upload($feedType, $feedContents);
$createFeedSpec = new CreateFeedSpecification(
marketplaceIds: ['ATVPDKIKX0DER'],
inputFeedDocumentId: $feedDocument->feedDocumentId,
feedType: $feedType,
);
// Create feed with the feed document we just uploaded
$createFeedResponse = $feedsApi->createFeed($createFeedSpec);
$feedId = $createFeedResponse->dto()->feedId;
If you are working with feed documents that are too large to fit in memory, you can pass anything that Guzzle can turn into a stream into FeedDocument::upload()
instead of a string.
This process is very similar to downloading a report document:
use SellingPartnerApi\SellingPartnerApi;
$feedType = 'POST_PRODUCT_PRICING_DATA';
// Assume we already got a feed result document ID from a previous getFeed call
$documentId = '1234567890.asdf';
$connector = SellingPartnerApi::make(/* ... */)->seller();
$response = $connector->feeds()->getFeedDocument($documentId);
$feedDocument = $response->dto();
$contents = $feedResultDocument->download($feedType);
Wherever possible, the names of the classes, methods, and properties in this package are identical to the names used in the Selling Partner API documentation. There are limited cases where this is not true, such as where the SP API documentation itself is inconsistent: for instance, there are some cases the SP API docs name properties in UpperCamelCase
instead of camelCase
, and in those cases the properties are named in camelCase
in this package. Methods are named in camelCase
, and DTOs are named in UpperCamelCase
.
Instead of maintaining a redundant set of documentation, we link to the official SP API documentation whenever possible. If it's unclear how to use a particular method or DTO, check out the corresponding section of the official SP API documentation.
Some Selling Partner API segments have multiple versions. For instance, the Product Pricing API has two versions: v0
and v2022-05-01
. The connector method SellerConnector::productPricing()
points to the newer version (v2022-05-01
), but you can get an instance of the older version by calling SellerConnector::productPricingV0()
. Or, if you want to explicitly specify v2022-05-01
in a way that will not break in a future major release if a new version of the API is introduced, you can call SellerConnector::productPricingV20220501()
.
More generally, the latest version of a given API segment (at the time when the major version of this library you're using was released) can be accessed with Connector::apiName()
. Specific versions can be accessed with Connector::apiNameV<version>()
.
Some methods take DTOs as parameters. For instance, the confirmShipment
method in the Orders API takes a ConfirmShipmentRequest
DTO as a parameter. You can call confirmShipment
like so:
<?php
use SellingPartnerApi\Seller\OrdersV0\Dto;
use SellingPartnerApi\SellingPartnerApi;
$confirmShipmentRequest = new Dto\ConfirmShipmentRequest(
packageDetail: new Dto\PackageDetail(
packageReferenceId: 'PKG123',
carrierCode: 'USPS',
trackingNumber: 'ASDF1234567890',
shipDate: new DateTime('2024-01-01 12:00:00'),
orderItems: [
new Dto\ConfirmShipmentOrderItem(
orderItemId: '1234567890',
quantity: 1,
),
new Dto\ConfirmShipmentOrderItem(
orderItemId: '0987654321',
quantity: 2,
)
],
),
marketplaceId: 'ATVPDKIKX0DER',
);
$response = $ordersApi->confirmShipment(
orderId: '123-4567890-1234567',
confirmShipmentRequest: $confirmShipmentRequest,
)