TL;DR
Die Amazon Selling Partner API (SP-API) ist eine REST-basierte API, die programmatischen Zugriff auf Verkäuferdaten für Bestellungen, Lagerbestand, Angebote und Fulfillment ermöglicht. Sie verwendet OAuth 2.0-Authentifizierung mit IAM-Rollen, erfordert AWS SigV4-Signierung und erzwingt Ratenbegrenzungen, die je nach Endpunkt variieren (0,1 bis 100 Anfragen pro Sekunde). Dieser Leitfaden behandelt die Kontoeinrichtung, Authentifizierung, Kern-Endpunkte, Webhook-Abonnements und Strategien für die Produktionsbereitstellung.
Einführung
Amazon verarbeitet über 350 Millionen Produkte auf mehr als 200 Marktplätzen weltweit. Für Entwickler, die E-Commerce-Tools, Bestandsverwaltungssysteme oder Analyseplattformen entwickeln, ist die Amazon SP-API-Integration nicht optional, sondern unerlässlich.
Die Realität sieht so aus: Verkäufer, die Amazon-Operationen verwalten, verlieren 20-30 Stunden pro Woche durch manuelle Dateneingabe bei Bestellungen, Lagerbestand und Angeboten. Eine solide SP-API-Integration automatisiert die Bestellsynchronisierung, Bestandsaktualisierungen und die Angebotsverwaltung über mehrere Marktplätze hinweg.
Dieser Leitfaden führt Sie durch den gesamten Amazon SP-API-Integrationsprozess. Sie lernen die Einrichtung von IAM-Rollen, die OAuth 2.0-Autorisierung, die AWS SigV4-Anforderungssignierung, die Bestell- und Bestandsverwaltung, Benachrichtigungsabonnements und die Fehlerbehebung kennen. Am Ende verfügen Sie über eine produktionsreife Amazon-Integration.
Was ist die Amazon SP-API?
Die Amazon Selling Partner API (SP-API) ist eine REST-basierte API, die programmatischen Zugriff auf Seller Central-Daten bietet. Sie ersetzte den älteren Marketplace Web Service (MWS) mit verbesserter Sicherheit, Leistung und Funktionalität.
Wichtige Funktionen
Die SP-API verarbeitet:
- Abruf von Bestellungen und Statusaktualisierungen
- Bestandsverwaltung über Marktplätze hinweg
- Erstellung, Aktualisierung und Löschung von Angeboten
- FBA (Fulfillment by Amazon) Sendungsverwaltung
- Produktpreise und Wettbewerbsanalyse
- Berichts- und Analysegenerierung
- Verwaltung von A+ Inhalten
- Markenanalyse und Werbedaten
SP-API vs. MWS Vergleich
| Funktion | SP-API | MWS (veraltet) |
|---|---|---|
| Architektur | RESTful JSON | XML-basiert |
| Authentifizierung | OAuth 2.0 + IAM | MWS Auth Token |
| Sicherheit | AWS SigV4-Signierung | Einfache Tokens |
| Ratenbegrenzungen | Dynamisch pro Endpunkt | Feste Kontingente |
| Marktplätze | Einheitliche Endpunkte | Regionsspezifisch |
| Status | Aktuell | Veraltet (Dez. 2025) |
Migrieren Sie alle MWS-Integrationen sofort auf die SP-API. Amazon hat die vollständige Einstellung von MWS für Dezember 2025 angekündigt.
Übersicht über die API-Architektur
Amazon verwendet eine regionale API-Struktur mit zentralisierter Autorisierung:
https://sellingpartnerapi-na.amazon.com (Nordamerika)
https://sellingpartnerapi-eu.amazon.com (Europa)
https://sellingpartnerapi-fe.amazon.com (Fernost)
Alle Anfragen erfordern:
- AWS SigV4-Signatur
- Zugangstoken aus dem OAuth-Fluss
- Korrekte IAM-Rollenberechtigungen
- Anforderungs-ID zur Nachverfolgung
Unterstützte Marktplätze
| Region | Marktplätze | API-Endpunkt |
|---|---|---|
| Nordamerika | US, CA, MX | sellingpartnerapi-na.amazon.com |
| Europa | UK, DE, FR, IT, ES, NL, SE, PL, TR, EG, IN, AE, SA | sellingpartnerapi-eu.amazon.com |
| Fernost | JP, AU, SG, BR | sellingpartnerapi-fe.amazon.com |
Erste Schritte: Konto- und IAM-Einrichtung
Schritt 1: Erstellen Sie Ihr Amazon Developer-Konto
Bevor Sie auf die SP-API zugreifen, benötigen Sie die richtigen Kontozugangsdaten:
- Besuchen Sie das Amazon Developer Central
- Melden Sie sich mit Ihrem Amazon-Konto an (muss Seller Central-Zugriff haben)
- Navigieren Sie im Dashboard zu Selling Partner API
- Akzeptieren Sie die Entwicklervereinbarung
Schritt 2: Registrieren Sie Ihre Anwendung
Erstellen Sie ein Anwendungsprofil in Seller Central:
- Melden Sie sich bei Seller Central an
- Navigieren Sie zu Apps und Dienste > Apps entwickeln
- Klicken Sie auf Neue App hinzufügen
- Geben Sie die Anwendungsdetails ein:
- Anwendungsname: Klarer, beschreibender Name
- Anwendungstyp: Wählen Sie „Selbst entwickelt“ oder „Drittanbieter“
- Anwendungsfall: Beschreiben Sie den Zweck Ihrer Integration
- Umleitungs-URI: HTTPS-URL für den OAuth-Callback
Nach der Übermittlung erhalten Sie:
- Anwendungs-ID: Ihre öffentliche Anwendungs-ID
- Client-ID: Wird in der OAuth-Autorisierungs-URL verwendet
- Client-Geheimnis: Ihr privates API-Geheimnis (niemals offenlegen)
Sicherheitshinweis: Speichern Sie Anmeldeinformationen in Umgebungsvariablen, niemals im Code:
# .env file
AMAZON_APPLICATION_ID="amzn1.application.xxxxx"
AMAZON_CLIENT_ID="amzn1.account.xxxxx"
AMAZON_CLIENT_SECRET="your_client_secret_here"
AMAZON_SELLER_ID="your_seller_id_here"
AWS_ACCESS_KEY_ID="your_aws_access_key"
AWS_SECRET_ACCESS_KEY="your_aws_secret_key"
AWS_REGION="us-east-1"
Schritt 3: IAM-Rolle für SP-API erstellen
Die SP-API erfordert eine IAM-Rolle mit spezifischen Berechtigungen:
- Melden Sie sich bei der AWS IAM-Konsole an
- Navigieren Sie zu Rollen > Rolle erstellen
- Wählen Sie Anderes AWS-Konto als vertrauenswürdige Entität
- Geben Sie die Amazon-Konto-ID für Ihre Region ein:
- Nordamerika:
906394416454 - Europa:
336853085554 - Fernost:
774466381866
Schritt 4: IAM-Richtlinie konfigurieren
Fügen Sie diese Richtlinie Ihrer IAM-Rolle hinzu:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"execute-api:Invoke"
],
"Resource": [
"arn:aws:execute-api:*:*:*/prod/*/sellingpartnerapi/*"
]
}
]
}
Benennen Sie Ihre Rolle aussagekräftig, z. B. SellingPartnerApiRole, und notieren Sie den ARN.
Schritt 5: IAM-Rolle mit der Anwendung verknüpfen
Verbinden Sie Ihre IAM-Rolle mit der SP-API-Anwendung:
- Kehren Sie zu Seller Central > Apps entwickeln zurück
- Wählen Sie Ihre Anwendung aus
- Klicken Sie auf Bearbeiten > IAM Role ARN
- Geben Sie Ihren IAM-Rollen-ARN ein
- Speichern Sie die Änderungen
Amazon validiert die IAM-Rolle innerhalb weniger Minuten. Sie sehen den Status „Verknüpft“, sobald sie bereit ist.
OAuth 2.0 Authentifizierungsfluss
SP-API OAuth verstehen
Amazon verwendet OAuth 2.0 zur Autorisierung. Hier ist der vollständige Ablauf:
1. Verkäufer klickt in Ihrer Anwendung auf "Autorisieren".
2. Ihre App leitet zur Amazon-Autorisierungs-URL weiter.
3. Verkäufer meldet sich an und erteilt Berechtigungen.
4. Amazon leitet mit einem Autorisierungscode zurück.
5. Ihre App tauscht den Code gegen ein LWA-Token (Login with Amazon) aus.
6. Ihre App tauscht das LWA-Token gegen ein SP-API-Zugriffstoken aus.
7. Ihre App verwendet das Zugriffstoken für API-Aufrufe (SigV4-signiert).
8. Token aktualisieren, wenn das Zugriffstoken abläuft (1 Stunde).
Schritt 6: Autorisierungs-URL generieren
Erstellen Sie die OAuth-Autorisierungs-URL:
const generateAuthUrl = (clientId, redirectUri, state) => {
const baseUrl = 'https://www.amazon.com/sp/apps/oauth/authorize';
const params = new URLSearchParams({
application_id: process.env.AMAZON_APPLICATION_ID,
client_id: clientId,
redirect_uri: redirectUri,
state: state, // Random string for CSRF protection
scope: 'sellingpartnerapi::notifications'
});
return `${baseUrl}?${params.toString()}`;
};
// Usage
const authUrl = generateAuthUrl(
process.env.AMAZON_CLIENT_ID,
'https://your-app.com/callback',
crypto.randomBytes(16).toString('hex')
);
console.log(`Redirect user to: ${authUrl}`);
Erforderliche OAuth-Bereiche (Scopes)
Fordern Sie nur die Berechtigungen an, die Ihre Anwendung benötigt:
| Bereich (Scope) | Beschreibung | Anwendungsfall |
|---|---|---|
sellingpartnerapi::notifications |
Benachrichtigungen erhalten | Webhook-Abonnements |
sellingpartnerapi::migration |
Von MWS migrieren | Veraltete Integrationen |
Die meisten API-Zugriffe werden durch IAM-Richtlinien und nicht durch OAuth-Scopes gesteuert.
Schritt 7: Code gegen LWA-Token austauschen
Behandeln Sie den OAuth-Callback und tauschen Sie den Autorisierungscode aus:
const exchangeCodeForLwaToken = async (code, redirectUri) => {
const response = await fetch('https://api.amazon.com/auth/o2/token', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/x-www-form-urlencoded'
},
body: new URLSearchParams({
grant_type: 'authorization_code',
client_id: process.env.AMAZON_CLIENT_ID,
client_secret: process.env.AMAZON_CLIENT_SECRET,
redirect_uri: redirectUri,
code: code
})
});
if (!response.ok) {
const error = await response.json();
throw new Error(`LWA Token Error: ${error.error_description}`);
}
const data = await response.json();
return {
access_token: data.access_token,
refresh_token: data.refresh_token,
expires_in: data.expires_in, // Typically 3600 seconds (1 hour)
token_type: data.token_type
};
};
// Handle callback route
app.get('/callback', async (req, res) => {
const { spapi_oauth_code, state } = req.query;
// Verify state matches what you sent (CSRF protection)
if (state !== req.session.oauthState) {
return res.status(400).send('Invalid state parameter');
}
try {
const tokens = await exchangeCodeForLwaToken(spapi_oauth_code, 'https://your-app.com/callback');
// Store tokens in database associated with seller
await db.sellers.update(req.session.sellerId, {
amazon_lwa_access_token: tokens.access_token,
amazon_lwa_refresh_token: tokens.refresh_token,
amazon_token_expires: Date.now() + (tokens.expires_in * 1000)
});
res.redirect('/dashboard');
} catch (error) {
console.error('Token exchange failed:', error);
res.status(500).send('Authentication failed');
}
});
Schritt 8: LWA-Token gegen SP-API-Anmeldeinformationen tauschen
Verwenden Sie das LWA-Zugriffstoken, um temporäre AWS-Anmeldeinformationen zu erhalten:
const assumeRole = async (lwaAccessToken) => {
const response = await fetch('https://api.amazon.com/auth/o2/token', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/x-www-form-urlencoded'
},
body: new URLSearchParams({
grant_type: 'client_credentials',
client_id: process.env.AMAZON_CLIENT_ID,
client_secret: process.env.AMAZON_CLIENT_SECRET,
scope: 'sellingpartnerapi::notifications'
})
});
const data = await response.json();
// Exchange for AWS credentials via STS
const stsResponse = await fetch('https://sts.amazonaws.com/', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': `Bearer ${data.access_token}`
},
body: new URLSearchParams({
Action: 'AssumeRole',
RoleArn: 'arn:aws:iam::YOUR_ACCOUNT:role/SellingPartnerApiRole',
RoleSessionName: 'sp-api-session',
Version: '2011-06-15'
})
});
return stsResponse;
};
Schritt 9: Token-Aktualisierung implementieren
Zugriffstoken verfallen nach 1 Stunde. Implementieren Sie eine automatische Aktualisierung:
const refreshLwaToken = async (refreshToken) => {
const response = await fetch('https://api.amazon.com/auth/o2/token', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/x-www-form-urlencoded'
},
body: new URLSearchParams({
grant_type: 'refresh_token',
client_id: process.env.AMAZON_CLIENT_ID,
client_secret: process.env.AMAZON_CLIENT_SECRET,
refresh_token: refreshToken
})
});
const data = await response.json();
return {
access_token: data.access_token,
refresh_token: data.refresh_token, // Always save the new refresh token
expires_in: data.expires_in
};
};
// Middleware to ensure valid token
const ensureValidToken = async (sellerId) => {
const seller = await db.sellers.findById(sellerId);
// Check if token expires within 5 minutes
if (seller.amazon_token_expires < Date.now() + 300000) {
const newTokens = await refreshLwaToken(seller.amazon_lwa_refresh_token);
await db.sellers.update(sellerId, {
amazon_lwa_access_token: newTokens.access_token,
amazon_lwa_refresh_token: newTokens.refresh_token,
amazon_token_expires: Date.now() + (newTokens.expires_in * 1000)
});
return newTokens.access_token;
}
return seller.amazon_lwa_access_token;
};
AWS SigV4 Anforderungssignierung
SigV4 verstehen
Alle SP-API-Anfragen erfordern die AWS Signature Version 4 (SigV4)-Signierung. Dies gewährleistet die Authentizität und Integrität der Anfrage.
SigV4 Signierungsprozess
const crypto = require('crypto');
class SigV4Signer {
constructor(accessKey, secretKey, region, service = 'execute-api') {
this.accessKey = accessKey;
this.secretKey = secretKey;
this.region = region;
this.service = service;
}
sign(method, url, body = '', headers = {}) {
const parsedUrl = new URL(url);
const now = new Date();
// Step 1: Create canonical request
const amzDate = now.toISOString().replace(/[:-]|\.\d{3}/g, '');
const dateStamp = amzDate.slice(0, 8);
headers['host'] = parsedUrl.host;
headers['x-amz-date'] = amzDate;
headers['x-amz-access-token'] = this.accessToken;
headers['content-type'] = 'application/json';
const canonicalHeaders = Object.entries(headers)
.sort(([a], [b]) => a.localeCompare(b))
.map(([k, v]) => `${k.toLowerCase()}:${v.trim()}`)
.join('\n');
const signedHeaders = Object.keys(headers)
.sort()
.map(k => k.toLowerCase())
.join(';');
const payloadHash = crypto.createHash('sha256').update(body).digest('hex');
const canonicalRequest = [
method.toUpperCase(),
parsedUrl.pathname,
parsedUrl.search.slice(1),
canonicalHeaders,
'',
signedHeaders,
payloadHash
].join('\n');
// Step 2: Create string to sign
const algorithm = 'AWS4-HMAC-SHA256';
const credentialScope = `${dateStamp}/${this.region}/${this.service}/aws4_request`;
const stringToSign = [
algorithm,
amzDate,
credentialScope,
crypto.createHash('sha256').update(canonicalRequest).digest('hex')
].join('\n');
// Step 3: Calculate signature
const kDate = this.hmac(`AWS4${this.secretKey}`, dateStamp);
const kRegion = this.hmac(kDate, this.region);
const kService = this.hmac(kRegion, this.service);
const kSigning = this.hmac(kService, 'aws4_request');
const signature = this.hmac(kSigning, stringToSign, 'hex');
// Step 4: Add authorization header
const authorization = `${algorithm} Credential=${this.accessKey}/${credentialScope}, SignedHeaders=${signedHeaders}, Signature=${signature}`;
return {
headers: {
...headers,
'Authorization': authorization
},
canonicalRequest,
stringToSign,
signature
};
}
hmac(key, data, encoding = 'buffer') {
return crypto.createHmac('sha256', key).update(data).digest(encoding);
}
}
// Usage
const signer = new SigV4Signer(
process.env.AWS_ACCESS_KEY_ID,
process.env.AWS_SECRET_ACCESS_KEY,
'us-east-1'
);
const signedRequest = signer.sign('GET', 'https://sellingpartnerapi-na.amazon.com/orders/v0/orders', '', {
'x-amz-access-token': accessToken
});
AWS SDK für SigV4 verwenden
Vereinfachen Sie die Signierung mit dem AWS SDK:
const { SignatureV4 } = require('@aws-sdk/signature-v4');
const { Sha256 } = require('@aws-crypto/sha256-js');
const signer = new SignatureV4({
credentials: {
accessKeyId: process.env.AWS_ACCESS_KEY_ID,
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY
},
region: 'us-east-1',
service: 'execute-api',
sha256: Sha256
});
const makeSpApiRequest = async (method, endpoint, accessToken, body = null) => {
const url = new URL(endpoint);
const headers = {
'host': url.host,
'content-type': 'application/json',
'x-amz-access-token': accessToken,
'x-amz-date': new Date().toISOString().replace(/[:-]|\.\d{3}/g, '')
};
const signedRequest = await signer.sign({
method,
hostname: url.hostname,
path: url.pathname,
query: Object.fromEntries(url.searchParams),
headers,
body: body ? JSON.stringify(body) : undefined
});
const response = await fetch(endpoint, {
method,
headers: signedRequest.headers,
body: signedRequest.body
});
if (!response.ok) {
const error = await response.json();
throw new Error(`SP-API Error: ${error.errors?.[0]?.message || response.statusText}`);
}
return response.json();
};
Bestellungen API
Bestellungen abrufen
Bestellungen mit Filteroptionen abrufen:
const getOrders = async (accessToken, options = {}) => {
const params = new URLSearchParams({
createdAfter: options.createdAfter, // ISO 8601 format
createdBefore: options.createdBefore,
orderStatuses: options.orderStatuses?.join(',') || '',
marketplaceIds: options.marketplaceIds?.join(',') || ['ATVPDKIKX0DER'], // US
maxResultsPerPage: options.maxResultsPerPage || 100
});
// Remove empty params
for (const [key, value] of params.entries()) {
if (!value) params.delete(key);
}
const endpoint = `https://sellingpartnerapi-na.amazon.com/orders/v0/orders?${params.toString()}`;
return makeSpApiRequest('GET', endpoint, accessToken);
};
// Usage example
const orders = await getOrders(accessToken, {
createdAfter: new Date(Date.now() - 24 * 60 * 60 * 1000).toISOString(), // Last 24 hours
orderStatuses: ['Unshipped', 'PartiallyShipped'],
marketplaceIds: ['ATVPDKIKX0DER'] // US marketplace
});
Struktur der Bestellantwort
{
"payload": {
"orders": [
{
"amazon_order_id": "112-1234567-1234567",
"seller_order_id": "ORDER-001",
"purchase_date": "2026-03-19T10:30:00Z",
"last_update_date": "2026-03-19T14:45:00Z",
"order_status": "Unshipped",
"fulfillment_channel": "AFN", // AFN = FBA, MFN = Merchant
"sales_channel": "Amazon.com",
"order_channel": "Amazon.com",
"ship_service_level": "Std US D2D Dom",
"order_total": {
"currency_code": "USD",
"amount": "89.99"
},
"number_of_items_shipped": 0,
"number_of_items_unshipped": 2,
"payment_execution_detail": [],
"payment_method": "CreditCard",
"payment_method_details": ["CreditCard"],
"marketplace_id": "ATVPDKIKX0DER",
"shipment_service_level_category": "Standard",
"easy_ship_shipment_status": null,
"is_business_order": false,
"is_prime": true,
"is_premium_order": false,
"is_global_express_enabled": false
}
],
"next_token": "eyJleHBpcmF0aW9uVGltZU9mTmV4dFRva2VuIjoxNzEwOTUwNDAwfQ=="
}
}
Bestellpositionen abrufen
Detaillierte Positionen für eine Bestellung abrufen:
const getOrderItems = async (accessToken, orderId) => {
const endpoint = `https://sellingpartnerapi-na.amazon.com/orders/v0/orders/${orderId}/orderItems`;
return makeSpApiRequest('GET', endpoint, accessToken);
};
// Usage
const orderItems = await getOrderItems(accessToken, '112-1234567-1234567');
// Expected response
{
"payload": {
"order_items": [
{
"asin": "B08N5WRWNW",
"seller_sku": "MYSKU-001",
"title": "Wireless Bluetooth Headphones",
"quantity_ordered": 2,
"quantity_shipped": 0,
"product_info": {
"number_of_items": 2
},
"item_price": {
"currency_code": "USD",
"amount": "44.99"
},
"item_total": {
"currency_code": "USD",
"amount": "89.98"
},
"tax_collection": {
"tax_collection_model": "MarketplaceFacilitator",
"responsible_party": "Amazon Services, Inc."
}
}
]
}
}
Versandstatus aktualisieren
Bestellungen mit Sendungsverfolgungsinformationen als versendet markieren:
const confirmShipment = async (accessToken, orderId, shipmentData) => {
const endpoint = `https://sellingpartnerapi-na.amazon.com/orders/v0/orders/${orderId}/shipmentConfirmation`;
const payload = {
packageDetails: {
packageReferenceId: shipmentData.packageReferenceId || '1',
carrier_code: shipmentData.carrierCode, // e.g., 'USPS', 'FEDEX', 'UPS'
tracking_number: shipmentData.trackingNumber,
ship_date: shipmentData.shipDate || new Date().toISOString(),
items: shipmentData.items.map(item => ({
order_item_id: item.orderItemId,
quantity: item.quantity
}))
}
};
return makeSpApiRequest('POST', endpoint, accessToken, payload);
};
// Usage
await confirmShipment(accessToken, '112-1234567-1234567', {
carrierCode: 'USPS',
trackingNumber: '9400111899223456789012',
items: [
{ orderItemId: '12345678901234', quantity: 2 }
]
});
Gängige Spediteur-Codes
| Spediteur | Spediteur-Code |
|---|---|
| USPS | USPS |
| FedEx | FEDEX |
| UPS | UPS |
| DHL | DHL |
| Canada Post | CANADA_POST |
| Royal Mail | ROYAL_MAIL |
| Australia Post | AUSTRALIA_POST |
| Amazon Logistics | AMZN_UK |
Bestands-API
Bestandsübersichten abrufen
Bestandsmengen über Marktplätze hinweg abrufen:
const getInventorySummaries = async (accessToken, options = {}) => {
const params = new URLSearchParams({
granularityType: options.granularityType || 'Marketplace',
granularityId: options.granularityId || 'ATVPDKIKX0DER', // US
startDateTime: options.startDateTime || '',
sellerSkus: options.sellerSkus?.join(',') || ''
});
const endpoint = `https://sellingpartnerapi-na.amazon.com/fba/inventory/v1/summaries?${params.toString()}`;
return makeSpApiRequest('GET', endpoint, accessToken);
};
// Usage
const inventory = await getInventorySummaries(accessToken, {
granularityId: 'ATVPDKIKX0DER',
sellerSkus: ['MYSKU-001', 'MYSKU-002']
});
Struktur der Bestandsantwort
{
"payload": {
"inventorySummaries": [
{
"asin": "B08N5WRWNW",
"seller_sku": "MYSKU-001",
"condition": "NewItem",
"details": {
"quantity": 150,
"fulfillable_quantity": 145,
"inbound_working_quantity": 0,
"inbound_shipped_quantity": 5,
"inbound_receiving_quantity": 0,
"reserved_quantity": 5,
"unfulfillable_quantity": 0,
"warehouse_damage_quantity": 0,
"distributor_damaged_quantity": 0,
"carrier_damaged_quantity": 0,
"defective_quantity": 0,
"customer_damaged_quantity": 0
},
"marketplace_id": "ATVPDKIKX0DER"
}
]
}
}
Bestand aktualisieren
Hinweis: Die SP-API bietet keine direkten Endpunkte zur Bestandsaktualisierung. Der Bestand wird über folgende Wege verwaltet:
- FBA-Sendungen – Bestand an Amazon-Lagerhäuser senden
- MFN-Bestellungen – Der Bestand reduziert sich automatisch, wenn Bestellungen versendet werden
- Angebotsaktualisierungen – Menge über die Listings API anpassen
Für FBA, erstellen Sie Versandpläne:
const createInboundShipmentPlan = async (accessToken, shipmentData) => {
const endpoint = 'https://sellingpartnerapi-na.amazon.com/fba/inbound/v0/plans';
const payload = {
ShipFromAddress: {
Name: shipmentData.shipFromName,
AddressLine1: shipmentData.shipFromAddress,
City: shipmentData.shipFromCity,
StateOrProvinceCode: shipmentData.shipFromState,
CountryCode: shipmentData.shipFromCountry,
PostalCode: shipmentData.shipFromPostalCode
},
LabelPrepPreference: 'SELLER_LABEL',
InboundPlanItems: shipmentData.items.map(item => ({
SellerSKU: item.sku,
ASIN: item.asin,
Quantity: item.quantity,
Condition: 'NewItem'
}))
};
return makeSpApiRequest('POST', endpoint, accessToken, payload);
};
Angebots-API
Angebote abrufen
Produktangebote mit Filterung abrufen:
const getListings = async (accessToken, options = {}) => {
const params = new URLSearchParams({
marketplaceIds: options.marketplaceIds?.join(',') || ['ATVPDKIKX0DER'],
itemTypes: options.itemTypes?.join(',') || ['ASIN', 'SKU'],
identifiers: options.identifiers?.join(',') || '',
issuesLocale: options.locale || 'en_US'
});
const endpoint = `https://sellingpartnerapi-na.amazon.com/listings/2021-08-01/items?${params.toString()}`;
return makeSpApiRequest('GET', endpoint, accessToken);
};
// Usage
const listings = await getListings(accessToken, {
identifiers: ['B08N5WRWNW', 'B09JQKJXYZ'],
itemTypes: ['ASIN']
});
Struktur der Angebotsantwort
{
"identifiers": {
"marketplaceId": "ATVPDKIKX0DER",
"sku": "MYSKU-001",
"asin": "B08N5WRWNW"
},
"attributes": {
"title": "Wireless Bluetooth Headphones",
"description": "Premium wireless headphones with noise cancellation",
"brand": "MyBrand",
"color": "Black",
"size": "One Size",
"item_weight": "0.5 pounds",
"product_dimensions": "7 x 6 x 3 inches"
},
"product_type": "LUGGAGE",
"sales_price": {
"currency_code": "USD",
"amount": "89.99"
},
"list_price": {
"currency_code": "USD",
"amount": "129.99"
},
"fulfillment_availability": [
{
"fulfillment_channel_code": "AFN",
"quantity": 150
}
],
"condition_type": "New",
"status": "ACTIVE",
"procurement": null
}
Angebote erstellen oder aktualisieren
Verwenden Sie `submitListingsSubmission` für Batch-Operationen:
const submitListingUpdate = async (accessToken, listingData) => {
const endpoint = 'https://sellingpartnerapi-na.amazon.com/listings/2021-08-01/items/MYSKU-001';
const payload = {
productType: 'LUGGAGE',
patches: [
{
op: 'replace',
path: '/attributes/title',
value: 'Updated Wireless Bluetooth Headphones - Premium Sound'
},
{
op: 'replace',
path: '/salesPrice',
value: {
currencyCode: 'USD',
amount: '79.99'
}
}
]
};
return makeSpApiRequest('PATCH', endpoint, accessToken, payload);
};
Ein Angebot löschen
Ein Angebot entfernen oder deaktivieren:
const deleteListing = async (accessToken, sku, marketplaceIds) => {
const params = new URLSearchParams({
marketplaceIds: marketplaceIds.join(',')
});
const endpoint = `https://sellingpartnerapi-na.amazon.com/listings/2021-08-01/items/${sku}?${params.toString()}`;
return makeSpApiRequest('DELETE', endpoint, accessToken);
};
Berichts-API
Berichtszeitpläne erstellen
Automatisieren Sie die Berichterstellung:
const createReport = async (accessToken, reportType, dateRange) => {
const endpoint = 'https://sellingpartnerapi-na.amazon.com/reports/2021-06-30/reports';
const payload = {
reportType: reportType,
marketplaceIds: dateRange.marketplaceIds || ['ATVPDKIKX0DER'],
dataStartTime: dateRange.startTime?.toISOString(),
dataEndTime: dateRange.endTime?.toISOString()
};
return makeSpApiRequest('POST', endpoint, accessToken, payload);
};
// Common report types
const REPORT_TYPES = {
ORDERS: 'GET_FLAT_FILE_ALL_ORDERS_DATA_BY_LAST_UPDATE_GENERAL',
ORDER_ITEMS: 'GET_FLAT_FILE_ORDER_ITEMS_DATA_BY_LAST_UPDATE_GENERAL',
INVENTORY: 'GET_MERCHANT_LISTINGS_ALL_DATA',
FBA_INVENTORY: 'GET_FBA_MYI_UNSUPPRESSED_INVENTORY_DATA',
SETTLEMENT: 'GET_V2_SETTLEMENT_REPORT_DATA_FLAT_FILE',
SALES_AND_TRAFFIC: 'GET_SALES_AND_TRAFFIC_REPORT',
ADVERTISING: 'GET_BRAND_ANALYTICS_SEARCH_TERMS_REPORT'
};
// Usage
const report = await createReport(accessToken, REPORT_TYPES.ORDERS, {
marketplaceIds: ['ATVPDKIKX0DER'],
startTime: new Date(Date.now() - 7 * 24 * 60 * 60 * 1000), // Last 7 days
endTime: new Date()
});
Berichtsdokument abrufen
Den generierten Bericht herunterladen:
const getReportDocument = async (accessToken, reportId) => {
const endpoint = `https://sellingpartnerapi-na.amazon.com/reports/2021-06-30/reports/${reportId}/document`;
return makeSpApiRequest('GET', endpoint, accessToken);
};
// Download and parse report
const downloadReport = async (accessToken, reportId) => {
const documentInfo = await getReportDocument(accessToken, reportId);
const response = await fetch(documentInfo.payload.url);
const content = await response.text();
// Reports are typically tab-delimited or JSON
if (documentInfo.payload.compressionAlgorithm === 'GZIP') {
const decompressed = await decompressGzip(content);
return decompressed;
}
return content;
};
Benachrichtigungs-API
Abonnements erstellen
Webhooks für Echtzeitereignisse einrichten:
const createSubscription = async (accessToken, subscriptionData) => {
const endpoint = 'https://sellingpartnerapi-na.amazon.com/notifications/v1/subscriptions';
const payload = {
payload: {
destination: {
resource: subscriptionData.destinationArn, // SNS topic ARN
name: subscriptionData.name
},
modelVersion: '1.0',
eventFilter: {
eventCode: subscriptionData.eventCode,
marketplaceIds: subscriptionData.marketplaceIds
}
}
};
return makeSpApiRequest('POST', endpoint, accessToken, payload);
};
// Available event types
const EVENT_CODES = {
ORDER_STATUS_CHANGE: 'OrderStatusChange',
ORDER_ITEM_CHANGE: 'OrderItemChange',
ORDER_CHANGE: 'OrderChange',
FBA_ORDER_STATUS_CHANGE: 'FBAOrderStatusChange',
FBA_OUTBOUND_SHIPMENT_STATUS: 'FBAOutboundShipmentStatus',
INVENTORY_LEVELS: 'InventoryLevels',
PRICING_HEALTH: 'PricingHealth'
};
// Usage
await createSubscription(accessToken, {
destinationArn: 'arn:aws:sns:us-east-1:123456789012:sp-api-notifications',
name: 'OrderStatusNotifications',
eventCode: EVENT_CODES.ORDER_STATUS_CHANGE,
marketplaceIds: ['ATVPDKIKX0DER']
});
SNS-Ziel einrichten
Amazon sendet Benachrichtigungen an SNS-Themen:
const createSnsDestination = async (accessToken, destinationData) => {
const endpoint = 'https://sellingpartnerapi-na.amazon.com/notifications/v1/destinations';
const payload = {
resource: destinationData.snsTopicArn,
name: destinationData.name
};
return makeSpApiRequest('POST', endpoint, accessToken, { payload });
};
// SNS topic policy must allow Amazon SES to publish
const snsTopicPolicy = {
Version: '2012-10-17',
Statement: [
{
Effect: 'Allow',
Principal: {
Service: 'notifications.amazon.com'
},
Action: 'SNS:Publish',
Resource: 'arn:aws:sns:us-east-1:123456789012:sp-api-notifications'
}
]
};
Benachrichtigungen verarbeiten
Richten Sie einen SNS-Endpunkt ein, um Benachrichtigungen zu empfangen:
const express = require('express');
const crypto = require('crypto');
const app = express();
app.post('/webhooks/amazon', express.raw({ type: 'application/json' }), async (req, res) => {
const signature = req.headers['x-amz-sns-message-signature'];
const payload = req.body;
// Verify SNS message signature
const isValid = await verifySnsSignature(payload, signature);
if (!isValid) {
console.error('Invalid SNS signature');
return res.status(401).send('Unauthorized');
}
const message = JSON.parse(payload.toString());
// Handle different message types
switch (message.Type) {
case 'SubscriptionConfirmation':
// Auto-confirm subscription
await fetch(message.SubscribeURL);
break;
case 'Notification':
const notification = JSON.parse(message.Message);
await handleSpApiNotification(notification);
break;
}
res.status(200).send('OK');
});
async function handleSpApiNotification(notification) {
const { notificationType, payload } = notification;
switch (notificationType) {
case 'OrderStatusChange':
await syncOrderStatus(payload.amazonOrderId);
break;
case 'OrderChange':
await syncOrderDetails(payload.amazonOrderId);
break;
case 'InventoryLevels':
await updateInventoryCache(payload);
break;
}
}
Ratenbegrenzungen und Quoten
Ratenbegrenzungen verstehen
Die SP-API erzwingt dynamische Ratenbegrenzungen pro Endpunkt:
| Endpunkt-Kategorie | Ratenbegrenzung | Burst-Grenze |
|---|---|---|
| Bestellungen | 10 Anfragen/Sekunde | 20 |
| Bestellpositionen | 5 Anfragen/Sekunde | 10 |
| Inventar | 2 Anfragen/Sekunde | 5 |
| Angebote | 10 Anfragen/Sekunde | 20 |
| Berichte | 0,5 Anfragen/Sekunde | 1 |
| Benachrichtigungen | 1 Anfrage/Sekunde | 2 |
| FBA Inbound | 2 Anfragen/Sekunde | 5 |
Überprüfen Sie den Header x-amzn-RateLimit-Limit in den Antworten für die aktuellen Limits.
Ratenbegrenzungsbehandlung implementieren
Verwenden Sie exponentielles Backoff für Wiederholungsversuche:
const makeRateLimitedRequest = async (method, endpoint, accessToken, body = null, maxRetries = 5) => {
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
const response = await makeSpApiRequest(method, endpoint, accessToken, body);
// Check rate limit headers
const rateLimit = response.headers.get('x-amzn-RateLimit-Limit');
const retryAfter = response.headers.get('Retry-After');
if (retryAfter) {
console.warn(`Rate limited. Retry after: ${retryAfter} seconds`);
}
return response;
} catch (error) {
if (error.message.includes('429') && attempt < maxRetries) {
// Extract retry-after header or use exponential backoff
const retryAfter = error.headers?.get('Retry-After') || Math.pow(2, attempt);
console.log(`Rate limited. Retrying in ${retryAfter}s...`);
await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
} else if (error.message.includes('503') && attempt < maxRetries) {
// Service unavailable - exponential backoff
const delay = Math.pow(2, attempt) * 1000;
console.log(`Service unavailable. Retrying in ${delay}ms...`);
await new Promise(resolve => setTimeout(resolve, delay));
} else {
throw error;
}
}
}
};
Implementierung der Anfragewarteschlange
Implementieren Sie eine Warteschlange, um innerhalb der Limits zu bleiben:
class RateLimitedQueue {
constructor(rateLimit, burstLimit = null) {
this.rateLimit = rateLimit; // requests per second
this.burstLimit = burstLimit || rateLimit * 2;
this.tokens = this.burstLimit;
this.lastRefill = Date.now();
this.queue = [];
this.processing = false;
}
async add(requestFn) {
return new Promise((resolve, reject) => {
this.queue.push({ requestFn, resolve, reject });
this.process();
});
}
refillTokens() {
const now = Date.now();
const elapsed = (now - this.lastRefill) / 1000;
const tokensToAdd = elapsed * this.rateLimit;
this.tokens = Math.min(this.burstLimit, this.tokens + tokensToAdd);
this.lastRefill = now;
}
async process() {
if (this.processing || this.queue.length === 0) return;
this.processing = true;
while (this.queue.length > 0) {
this.refillTokens();
if (this.tokens < 1) {
const waitTime = (1 / this.rateLimit) * 1000;
await new Promise(r => setTimeout(r, waitTime));
continue;
}
this.tokens--;
const { requestFn, resolve, reject } = this.queue.shift();
try {
const result = await requestFn();
resolve(result);
} catch (error) {
reject(error);
}
}
this.processing = false;
}
}
// Usage - Orders API queue (10 req/s)
const ordersQueue = new RateLimitedQueue(10, 20);
const orders = await ordersQueue.add(() => getOrders(accessToken, options));
Sicherheits-Best Practices
Anmeldeinformationsverwaltung
Anmeldeinformationen niemals fest im Quellcode hinterlegen. Verwenden Sie Umgebungsvariablen oder einen Secrets Manager:
// Bad - never do this
const AWS_ACCESS_KEY = 'AKIAIOSFODNN7EXAMPLE';
const AWS_SECRET = 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY';
// Good - use environment variables
const AWS_ACCESS_KEY = process.env.AWS_ACCESS_KEY_ID;
const AWS_SECRET = process.env.AWS_SECRET_ACCESS_KEY;
// Better - use AWS Secrets Manager or similar
const { SecretsManagerClient } = require('@aws-sdk/client-secrets-manager');
const secretsClient = new SecretsManagerClient({ region: 'us-east-1' });
const getCredentials = async () => {
const response = await secretsClient.send({
Name: 'prod/sp-api/credentials'
});
return JSON.parse(response.SecretString);
};
Anforderungen an die Token-Speicherung
Die SP-API erfordert spezifische Sicherheitsmaßnahmen für die Token-Speicherung:
- Verschlüsselung im Ruhezustand: Verwenden Sie AES-256-Verschlüsselung für gespeicherte Token
- Verschlüsselung während der Übertragung: Verwenden Sie immer HTTPS/TLS 1.2+
- Zugriffskontrollen: Beschränken Sie den Token-Zugriff auf spezifische Dienstkonten
- Audit-Protokollierung: Protokollieren Sie alle Token-Zugriffe und Aktualisierungsereignisse
- Automatische Rotation: Aktualisieren Sie Token vor dem Ablauf
const crypto = require('crypto');
class TokenStore {
constructor(encryptionKey) {
this.algorithm = 'aes-256-gcm';
this.key = crypto.createHash('sha256').update(encryptionKey).digest('hex').slice(0, 32);
}
encrypt(token) {
const iv = crypto.randomBytes(16);
const cipher = crypto.createCipheriv(this.algorithm, Buffer.from(this.key), iv);
let encrypted = cipher.update(token, 'utf8', 'hex');
encrypted += cipher.final('hex');
const authTag = cipher.getAuthTag().toString('hex');
return {
iv: iv.toString('hex'),
encryptedData: encrypted,
authTag
};
}
decrypt(encryptedData) {
const decipher = crypto.createDecipheriv(
this.algorithm,
Buffer.from(this.key),
Buffer.from(encryptedData.iv, 'hex')
);
decipher.setAuthTag(Buffer.from(encryptedData.authTag, 'hex'));
let decrypted = decipher.update(encryptedData.encryptedData, 'hex', 'utf8');
decrypted += decipher.final('utf8');
return decrypted;
}
}
IAM Prinzip des geringsten Privilegs
Erteilen Sie nur die Berechtigungen, die Ihre Anwendung benötigt:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "SPAPIOrdersAccess",
"Effect": "Allow",
"Action": "execute-api:Invoke",
"Resource": "arn:aws:execute-api:*:*:*/prod/*/sellingpartnerapi/orders/*"
},
{
"Sid": "SPAPIInventoryAccess",
"Effect": "Allow",
"Action": "execute-api:Invoke",
"Resource": "arn:aws:execute-api:*:*:*/prod/*/sellingpartnerapi/fba/inventory/*"
}
]
}
Vermeiden Sie die Verwendung von * Wildcards in der Produktion. Beschränken Sie Berechtigungen auf spezifische Endpunkte.
Sicherheit der Anforderungssignierung
Überprüfen Sie immer Ihre SigV4-Implementierung:
- Verwenden Sie HTTPS für alle Anfragen
- Fügen Sie alle erforderlichen Header in die Signatur ein
- Stellen Sie sicher, dass die Zeitstempel innerhalb von 5 Minuten der AWS-Server liegen
- Rotieren Sie AWS-Anmeldeinformationen regelmäßig
- Verwenden Sie nach Möglichkeit IAM-Rollen anstelle von Langzeit-Anmeldeinformationen
// Validate request timestamp
const validateTimestamp = (amzDate) => {
const now = new Date();
const requestTime = new Date(amzDate);
const diff = Math.abs(now - requestTime);
// AWS rejects requests older than 5 minutes
if (diff > 5 * 60 * 1000) {
throw new Error('Request timestamp too old. Sync your server clock.');
}
};
SP-API-Integrationen mit Apidog testen
Warum SP-API-Integrationen testen?
Amazon SP-API-Integrationen umfassen komplexe Authentifizierungsflüsse, mehrere Endpunkte und strenge Ratenbegrenzungen. Das Testen hilft Ihnen dabei:
- OAuth 2.0-Autorisierungsflüsse zu validieren
- SigV4-Signierungsprobleme zu debuggen
- Fehlerbehandlung für Ratenbegrenzungen zu testen
- Antworten für die Entwicklung zu simulieren
- API-Workflows für Ihr Team zu dokumentieren
Apidog für SP-API-Tests einrichten
Schritt 1: SP-API OpenAPI Spezifikation importieren
Apidog unterstützt OpenAPI 3.0 Spezifikationen. Importieren Sie die SP-API-Spezifikation von Amazon:
- Laden Sie die SP-API OpenAPI Spezifikation aus dem Amazon Repository herunter
- Erstellen Sie in Apidog ein neues Projekt
- Importieren Sie die Spezifikationsdatei
- Konfigurieren Sie Umgebungsvariablen für Anmeldeinformationen
Schritt 2: Umgebungsvariablen konfigurieren
Richten Sie umgebungsspezifische Variablen ein:
Basis-URL (Sandbox): https://sandbox.sellingpartnerapi-na.amazon.com
Basis-URL (Produktion): https://sellingpartnerapi-na.amazon.com
LWA Zugriffstoken: {{lwa_access_token}}
AWS Zugriffsschlüssel: {{aws_access_key}}
AWS Geheimschlüssel: {{aws_secret_key}}
Region: us-east-1
Schritt 3: Pre-Request-Skripte erstellen
Automatisieren Sie die SigV4-Signierung mit Apidog's Pre-Request-Skripten:
// Apidog pre-request script for SigV4 signing
const crypto = require('crypto');
const accessKey = apidog.variables.get('aws_access_key');
const secretKey = apidog.variables.get('aws_secret_key');
const accessToken = apidog.variables.get('lwa_access_token');
const region = apidog.variables.get('region');
const method = apidog.request.method;
const url = new URL(apidog.request.url);
const body = apidog.request.body;
// Generate SigV4 signature
const signer = new SigV4Signer(accessKey, secretKey, region);
const signedHeaders = signer.sign(method, url.href, body, {
'x-amz-access-token': accessToken
});
// Set headers for the request
apidog.request.headers = {
...apidog.request.headers,
...signedHeaders.headers
};
Schritt 4: Testszenarien erstellen
Erstellen Sie Testszenarien für gängige Workflows:
// Test: Get Orders from Last 24 Hours
// 1. Exchange OAuth code for token
// 2. Call GetOrders endpoint
// 3. Validate response structure
// 4. Extract order IDs
// 5. Call GetOrderItems for each order
const ordersResponse = await apidog.send({
method: 'GET',
url: '/orders/v0/orders',
params: {
createdAfter: new Date(Date.now() - 86400000).toISOString(),
marketplaceIds: 'ATVPDKIKX0DER'
}
});
apidog.assert(ordersResponse.status === 200, 'Orders request failed');
apidog.assert(ordersResponse.data.payload.orders.length > 0, 'No orders found');
// Store order IDs for subsequent requests
const orderIds = ordersResponse.data.payload.orders.map(o => o.amazon_order_id);
apidog.variables.set('order_ids', JSON.stringify(orderIds));
SP-API-Antworten simulieren
Verwenden Sie die intelligente Mock-Funktion von Apidog, um SP-API-Antworten während der Entwicklung zu simulieren:
// Mock response for GetOrders
{
"payload": {
"orders": [
{
"amazon_order_id": "112-{{randomNumber}}-{{randomNumber}}",
"order_status": "Unshipped",
"purchase_date": "{{now}}",
"order_total": {
"currency_code": "USD",
"amount": "{{randomFloat 10 500}}"
}
}
],
"next_token": null
}
}
Dies ermöglicht die Frontend-Entwicklung, ohne Live-Amazon-Endpunkte anzusprechen.
Häufige Probleme debuggen
Problem: SigV4-Signatur stimmt nicht überein
Verwenden Sie den Apidog-Anforderungsinspektor zur Überprüfung:
- Alle erforderlichen Header sind enthalten
- Header sind alphabetisch sortiert
- Die kanonische Anfrage entspricht den AWS-Erwartungen
- Der Zeitstempel liegt innerhalb des gültigen Bereichs
Problem: OAuth-Token-Fehler
Überprüfen Sie die Token-Gültigkeit mit einer einfachen Anfrage:
const tokenCheck = await apidog.send({
method: 'GET',
url: '/orders/v0/orders',
params: { createdAfter: new Date().toISOString() }
});
if (tokenCheck.status === 401) {
console.log('Token expired - refresh required');
// Trigger token refresh flow
}
Tests in CI/CD automatisieren
Integrieren Sie Apidog-Tests in Ihre CI/CD-Pipeline:
# GitHub Actions example
name: SP-API Integration Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run Apidog Tests
uses: apidog/test-action@v1
with:
project-id: ${{ secrets.APIDOG_PROJECT_ID }}
api-key: ${{ secrets.APIDOG_API_KEY }}
environment: sandbox
- name: Notify on Failure
if: failure()
run: |
echo "SP-API tests failed - check Apidog dashboard"
Referenz der Marktplatz-IDs
Halten Sie diese Referenz für gängige Marktplätze bereit:
| Land | Marktplatz-ID |
|---|---|
| Vereinigte Staaten | ATVPDKIKX0DER |
| Kanada | A2EUQ1WTGCTBG2 |
| Mexiko | A1AM78C64UM0Y8 |
| Vereinigtes Königreich | A1F83G8C2ARO7P |
| Deutschland | A1PA6795UKMFR9 |
| Frankreich | A13V1IB3VIYZZH |
| Italien | APJ6JRA9NG5V4 |
| Spanien | A1RKKUPIHCS9HS |
| Japan | A1VC38T7YXB528 |
| Australien | A39IBJ37TRP1C6 |
| Indien | A21TJRUUN4KGV |
| Brasilien | A2Q3Y263D00KWC |
Fehlerbehebung bei häufigen Problemen
Problem: 403 Unautorisierter Fehler
Symptome: Sie erhalten Fehlermeldungen wie „Unauthorized“ oder „Access Denied“.
Diagnose:
const error = await response.json();
console.error('Auth error:', error);
// Check: InvalidSignature, AccessDenied, ExpiredToken
Lösungen:
- Überprüfen Sie, ob die AWS-Anmeldeinformationen korrekt und aktiv sind
- Überprüfen Sie, ob die IAM-Rollen-ARN mit der Anwendung verknüpft ist
- Stellen Sie sicher, dass das OAuth-Token nicht abgelaufen ist
- Bestätigen Sie, dass die SigV4-Signatur die korrekte Region enthält
- Überprüfen Sie, ob der Header
x-amz-access-tokenvorhanden ist
Problem: 429 Ratenbegrenzung überschritten
Symptome: Sie erhalten häufig HTTP 429-Antworten.
Lösungen:
- Implementieren Sie eine Anforderungswarteschlange mit Ratenbegrenzung
- Verwenden Sie exponentielles Backoff für Wiederholungsversuche
- Fassen Sie Anfragen nach Möglichkeit zusammen (verwenden Sie next_token für die Paginierung)
- Überwachen Sie den Header
x-amzn-RateLimit-Limitproaktiv - Fordern Sie bei Seller Central höhere Limits für hochvolumige Anwendungsfälle an
Problem: 404 Nicht gefunden
Symptome: Gültige Endpunkte geben 404 zurück.
Lösungen:
- Vergewissern Sie sich, dass Sie den richtigen regionalen Endpunkt verwenden
- Überprüfen Sie, ob die Marktplatz-IDs für die Region gültig sind
- Bestätigen Sie, dass die Ressource (Bestellung, Angebot) existiert
- Stellen Sie sicher, dass die API-Version im Pfad korrekt ist (z. B.
/v0/,/2021-08-01/)
Problem: 400 Ungültige Anfrage
Symptome: Die Anfrage schlägt mit Validierungsfehlern fehl.
Häufige Ursachen:
- Ungültiges Datumsformat: Verwenden Sie das ISO 8601-Format (
2026-03-19T10:30:00Z) - Fehlende erforderliche Parameter: Überprüfen Sie die API-Dokumentation auf erforderliche Felder
- Ungültige Marktplatz-ID: Verwenden Sie korrekte IDs (z. B.
ATVPDKIKX0DERfür die USA) - Fehlerhaftes JSON: Überprüfen Sie die Syntax des Anfragetexts
Lösung:
// Validate dates before sending
const validateIsoDate = (dateString) => {
const date = new Date(dateString);
if (isNaN(date.getTime())) {
throw new Error('Invalid ISO 8601 date format');
}
return dateString;
};
Problem: Berichte bleiben im INIT_STATE
Symptome: Der Bericht erreicht nie den Status DONE.
Lösungen:
- Länger warten – einige Berichte dauern 15-30 Minuten
- Überprüfen Sie, ob der Berichtstyp für Ihr Konto verfügbar ist
- Stellen Sie sicher, dass der Datumsbereich nicht zu groß ist (versuchen Sie kleinere Bereiche)
- Rufen Sie den Berichtsstatus alle 30 Sekunden ab, nicht kontinuierlich
- Einige Berichtstypen erfordern spezifische Berechtigungen
Problem: Benachrichtigungen kommen nicht an
Symptome: Abonnements wurden erstellt, aber es werden keine Benachrichtigungen empfangen.
Diagnose:
- Überprüfen Sie den Abonnementstatus über die API
- Stellen Sie sicher, dass die SNS-Topic-Richtlinie Amazon SES zulässt
- Bestätigen Sie, dass die Endpunkt-URL öffentlich zugänglich ist
- Überprüfen Sie die CloudWatch-Protokolle auf Zustellversuche
Lösungen:
- Stellen Sie sicher, dass das SNS-Topic die korrekte Ressourcenrichtlinie besitzt
- Überprüfen Sie den HTTPS-Endpunkt mit einem gültigen SSL-Zertifikat
- Geben Sie innerhalb von 30 Sekunden für alle Benachrichtigungen einen 200 OK-Status zurück
- Bestätigen Sie automatisch
SubscriptionConfirmation-Nachrichten
Checkliste für die Produktionsbereitstellung
Bevor Sie live gehen:
- [ ] Anwendung in der Produktions-Seller Central registrieren
- [ ] Produktions-IAM-Rolle mit den geringsten erforderlichen Berechtigungen konfigurieren
- [ ] Alle Umleitungs-URIs auf Produktions-URLs aktualisieren
- [ ] Sichere Token-Speicherung implementieren (verschlüsselte Datenbank)
- [ ] Automatische Token-Aktualisierungslogik hinzufügen
- [ ] Ratenbegrenzung und Anforderungswarteschlange einrichten
- [ ] SNS-Ziel für Benachrichtigungen konfigurieren
- [ ] Umfassende Fehlerbehandlung implementieren
- [ ] Protokollierung für alle API-Aufrufe mit Anforderungs-IDs hinzufügen
- [ ] Überwachung der Ratenbegrenzungsnutzung einrichten
- [ ] Runbook für häufige Probleme erstellen
- [ ] Mit mehreren Marktplatz-IDs testen
- [ ] OAuth-Fluss für das Onboarding von Verkäufern dokumentieren
- [ ] Wiederholungslogik mit exponentiellem Backoff implementieren
- [ ] Benachrichtigungen für Authentifizierungsfehler einrichten
Monitoring und Alarmierung
Verfolgen Sie diese Metriken:
const metrics = {
apiCalls: {
total: 0,
successful: 0,
failed: 0,
rateLimited: 0
},
rateLimitUsage: {
orders: { current: 0, limit: 10 },
inventory: { current: 0, limit: 2 },
listings: { current: 0, limit: 10 }
},
oauthTokens: {
active: 0,
expiring_soon: 0,
refresh_failures: 0
},
notifications: {
received: 0,
processed: 0,
failed: 0
},
reports: {
pending: 0,
completed: 0,
failed: 0
}
};
// Alert on high failure rate
const failureRate = metrics.apiCalls.failed / metrics.apiCalls.total;
if (failureRate > 0.05) { // More than 5% failure rate
sendAlert('SP-API failure rate above 5%');
}
// Alert on rate limit approaching
for (const [endpoint, usage] of Object.entries(metrics.rateLimitUsage)) {
if (usage.current / usage.limit > 0.8) {
sendAlert(`${endpoint} rate limit at 80% capacity`);
}
}
Anwendungsfälle in der Praxis
Multi-Marktplatz-Bestandssynchronisation
Ein globaler Elektronikhändler nutzt die SP-API, um den Bestand über 12 Marktplätze hinweg zu synchronisieren:
- Herausforderung: Manuelle Bestandsaktualisierungen führten zu Überverkäufen auf EU-Marktplätzen
- Lösung: Zentrales Bestandssystem mit SP-API-Webhooks und ratenbegrenzten Warteschlangen
- Ergebnis: Keine Überverkäufe, 25 Stunden/Woche Zeitersparnis
Implementierungsfluss:
- SNS-Benachrichtigung wird bei
InventoryLevels-Ereignis ausgelöst - Zentrales System berechnet neue Mengen
- Ratenbegrenzte API-Aufrufe aktualisieren jeden Marktplatz
- Bestätigung wird in die Audit-Datenbank protokolliert
Automatisierte Auftragsabwicklung
Ein Drittanbieter-Logistikdienstleister automatisiert die Auftragsabwicklung:
- Herausforderung: Über 200 tägliche Bestellungen erforderten manuelle Dateneingabe in verschiedenen Systemen
- Lösung: SP-API-Integration mit Lagerverwaltungssystem
- Ergebnis: Bestellungen werden innerhalb von 2 Minuten nach Auftragserteilung automatisch an das Lager weitergeleitet
Wichtige Integrationspunkte:
- Webhook lauscht auf
OrderStatusChange-Ereignisse - Bestelldetails werden über REST-API an das WMS gesendet
- Sendungsverfolgungsnummer wird über SP-API zurückgegeben und aktualisiert
- Kunde erhält automatische Versandbenachrichtigung
Analyse-Dashboard
Ein Analyse-Tool für Verkäufer aggregiert Daten aus über 500 Verkäuferkonten:
- Herausforderung: Verkäufern fehlte eine einheitliche Berichterstattung über alle Marktplätze hinweg
- Lösung: OAuth-basierte Multi-Verkäufer-Datenaggregation mit Token-Verwaltung
- Ergebnis: Echtzeit-Dashboard mit Verkaufs-, Bestands- und Werbemetriken
Über die SP-API gesammelte Daten:
- Bestellungen und Bestellpositionen über alle Marktplätze hinweg
- FBA-Bestandsmengen und eingehende Sendungen
- Angebotsleistung und Preisdaten
- Markenanalyse und Suchbegriffsberichte
Fazit
Die Amazon SP-API bietet umfassenden Zugriff auf die Funktionen von Seller Central mit verbesserter Sicherheit und Leistung gegenüber der älteren MWS. Wichtige Erkenntnisse:
- OAuth 2.0 + IAM-Rollen erfordern eine sorgfältige Verwaltung der Anmeldeinformationen und eine automatische Token-Aktualisierung
- Die AWS SigV4-Signierung ist für alle Anfragen obligatorisch – verwenden Sie SDKs oder bewährte Bibliotheken
- Ratenbegrenzungen variieren je nach Endpunkt (0,5 bis 100 Anfragen/Sekunde) und erfordern eine proaktive Überwachung
- Benachrichtigungen über SNS ermöglichen die Echtzeit-Synchronisation von Bestellungen und Lagerbeständen
- Eine ordnungsgemäße Fehlerbehandlung und Wiederholungslogik sind für die Produktionszuverlässigkeit unerlässlich
- Apidog optimiert API-Tests und die Teamzusammenarbeit für SP-API-Integrationen
FAQ-Bereich
Was ist die Amazon SP-API?
Die Amazon Selling Partner API (SP-API) ist eine REST-basierte API, die programmatischen Zugriff auf Seller Central-Daten wie Bestellungen, Lagerbestand, Angebote und Berichte bietet. Sie ersetzte das ältere MWS-System durch verbesserte Sicherheit durch OAuth 2.0 und AWS SigV4-Signierung.
Wie erhalte ich Amazon SP-API-Anmeldeinformationen?
Registrieren Sie Ihre Anwendung in Seller Central unter Apps und Dienste > Apps entwickeln. Sie erhalten eine Client-ID, ein Client-Geheimnis und eine Anwendungs-ID. Sie müssen außerdem eine IAM-Rolle in AWS erstellen und diese mit Ihrer Anwendung verknüpfen.
Ist die Amazon SP-API kostenlos nutzbar?
Ja, der SP-API-Zugang ist für registrierte Amazon-Verkäufer kostenlos. Es gelten jedoch Ratenbegrenzungen, die je nach Endpunkt variieren (0,5 bis 100 Anfragen pro Sekunde). Höhere Limits erfordern die Genehmigung von Amazon für spezifische Anwendungsfälle mit hohem Volumen.
Welche Authentifizierung verwendet die SP-API?
Die SP-API verwendet OAuth 2.0 zur Autorisierung in Kombination mit AWS IAM-Rollen zur Zugriffssteuerung. Alle API-Anfragen erfordern die AWS Signature Version 4 (SigV4)-Signierung mit temporären Anmeldeinformationen, die über den OAuth-Fluss bezogen werden.
Wie gehe ich mit SP-API-Ratenbegrenzungen um?
Implementieren Sie eine Anforderungswarteschlange, um innerhalb der Endpunkt-Limits zu bleiben. Überwachen Sie den Header x-amzn-RateLimit-Limit, um die Nutzung zu verfolgen. Verwenden Sie exponentielles Backoff, wenn HTTP 429 (Too Many Requests) Antworten empfangen werden. Verschiedene Endpunkte haben unterschiedliche Limits.
Kann ich die SP-API ohne ein aktives Verkäuferkonto testen?
Ja. Amazon bietet eine Sandbox-Umgebung für die SP-API-Entwicklung. Registrieren Sie Ihre Anwendung im Sandbox-Modus, um Integrationen zu testen, ohne die Live-Verkäuferdaten zu beeinflussen. Beachten Sie, dass nicht alle Endpunkte in der Sandbox verfügbar sind.
Wie funktionieren Webhooks mit der SP-API?
Die SP-API verwendet Amazon SNS für Benachrichtigungen. Erstellen Sie ein Abonnement für bestimmte Ereignistypen (Bestellungen, Lagerbestand usw.), konfigurieren Sie ein SNS-Topic und implementieren Sie einen HTTPS-Endpunkt, um Benachrichtigungen zu empfangen. Bestätigen Sie Abonnementnachrichten automatisch.
Was passiert, wenn das OAuth-Token abläuft?
LWA-Zugriffstoken laufen nach 1 Stunde ab. Verwenden Sie das Refresh-Token, um vor dem Ablauf ein neues Zugriffstoken zu erhalten. Implementieren Sie eine automatische Token-Aktualisierung in Ihrer Middleware, um Authentifizierungsfehler während API-Aufrufen zu vermeiden.
Wie migriere ich von MWS zur SP-API?
Die Einstellung von MWS ist für Dezember 2025 geplant. Die Migration erfordert: Aktualisierung der Authentifizierung von MWS-Tokens auf OAuth 2.0, Implementierung der SigV4-Signierung, Aktualisierung der Endpunkt-URLs und Änderung der Anforderungs-/Antwortanalyse von XML auf JSON.
Warum erhalte ich 403 Unautorisierte Fehler?
Häufige Ursachen sind: abgelaufenes OAuth-Token, falsche IAM-Rollenkonfiguration, ungültige SigV4-Signatur, fehlender x-amz-access-token-Header oder nicht mit der Anwendung verknüpfte IAM-Rolle. Überprüfen Sie die Details der Fehlerantwort auf spezifische Fehlercodes.
