Amazon SP API Integration: Schritt-für-Schritt Anleitung

Ashley Innocent

Ashley Innocent

20 March 2026

Amazon SP API Integration: Schritt-für-Schritt Anleitung

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.

💡
Apidog vereinfacht das Testen der API-Integration. Testen Sie Ihre SP-API-Endpunkte, validieren Sie OAuth-Flüsse, überprüfen Sie Anforderungssignaturen und debuggen Sie Authentifizierungsprobleme in einem Arbeitsbereich. Importieren Sie API-Spezifikationen, modellieren Sie Antworten und teilen Sie Testszenarien mit Ihrem Team.
Button

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:

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:

  1. AWS SigV4-Signatur
  2. Zugangstoken aus dem OAuth-Fluss
  3. Korrekte IAM-Rollenberechtigungen
  4. 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:

  1. Besuchen Sie das Amazon Developer Central
  2. Melden Sie sich mit Ihrem Amazon-Konto an (muss Seller Central-Zugriff haben)
  3. Navigieren Sie im Dashboard zu Selling Partner API
  4. Akzeptieren Sie die Entwicklervereinbarung

Schritt 2: Registrieren Sie Ihre Anwendung

Erstellen Sie ein Anwendungsprofil in Seller Central:

  1. Melden Sie sich bei Seller Central an
  2. Navigieren Sie zu Apps und Dienste > Apps entwickeln
  3. Klicken Sie auf Neue App hinzufügen
  4. Geben Sie die Anwendungsdetails ein:

Nach der Übermittlung erhalten Sie:

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:

  1. Melden Sie sich bei der AWS IAM-Konsole an
  2. Navigieren Sie zu Rollen > Rolle erstellen
  3. Wählen Sie Anderes AWS-Konto als vertrauenswürdige Entität
  4. Geben Sie die Amazon-Konto-ID für Ihre Region ein:

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:

  1. Kehren Sie zu Seller Central > Apps entwickeln zurück
  2. Wählen Sie Ihre Anwendung aus
  3. Klicken Sie auf Bearbeiten > IAM Role ARN
  4. Geben Sie Ihren IAM-Rollen-ARN ein
  5. 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:

  1. FBA-Sendungen – Bestand an Amazon-Lagerhäuser senden
  2. MFN-Bestellungen – Der Bestand reduziert sich automatisch, wenn Bestellungen versendet werden
  3. 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:

  1. Verschlüsselung im Ruhezustand: Verwenden Sie AES-256-Verschlüsselung für gespeicherte Token
  2. Verschlüsselung während der Übertragung: Verwenden Sie immer HTTPS/TLS 1.2+
  3. Zugriffskontrollen: Beschränken Sie den Token-Zugriff auf spezifische Dienstkonten
  4. Audit-Protokollierung: Protokollieren Sie alle Token-Zugriffe und Aktualisierungsereignisse
  5. 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:

  1. Verwenden Sie HTTPS für alle Anfragen
  2. Fügen Sie alle erforderlichen Header in die Signatur ein
  3. Stellen Sie sicher, dass die Zeitstempel innerhalb von 5 Minuten der AWS-Server liegen
  4. Rotieren Sie AWS-Anmeldeinformationen regelmäßig
  5. 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:

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:

  1. Laden Sie die SP-API OpenAPI Spezifikation aus dem Amazon Repository herunter
  2. Erstellen Sie in Apidog ein neues Projekt
  3. Importieren Sie die Spezifikationsdatei
  4. 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:

  1. Alle erforderlichen Header sind enthalten
  2. Header sind alphabetisch sortiert
  3. Die kanonische Anfrage entspricht den AWS-Erwartungen
  4. 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:

  1. Überprüfen Sie, ob die AWS-Anmeldeinformationen korrekt und aktiv sind
  2. Überprüfen Sie, ob die IAM-Rollen-ARN mit der Anwendung verknüpft ist
  3. Stellen Sie sicher, dass das OAuth-Token nicht abgelaufen ist
  4. Bestätigen Sie, dass die SigV4-Signatur die korrekte Region enthält
  5. Überprüfen Sie, ob der Header x-amz-access-token vorhanden ist

Problem: 429 Ratenbegrenzung überschritten

Symptome: Sie erhalten häufig HTTP 429-Antworten.

Lösungen:

  1. Implementieren Sie eine Anforderungswarteschlange mit Ratenbegrenzung
  2. Verwenden Sie exponentielles Backoff für Wiederholungsversuche
  3. Fassen Sie Anfragen nach Möglichkeit zusammen (verwenden Sie next_token für die Paginierung)
  4. Überwachen Sie den Header x-amzn-RateLimit-Limit proaktiv
  5. 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:

  1. Vergewissern Sie sich, dass Sie den richtigen regionalen Endpunkt verwenden
  2. Überprüfen Sie, ob die Marktplatz-IDs für die Region gültig sind
  3. Bestätigen Sie, dass die Ressource (Bestellung, Angebot) existiert
  4. 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:

  1. Ungültiges Datumsformat: Verwenden Sie das ISO 8601-Format (2026-03-19T10:30:00Z)
  2. Fehlende erforderliche Parameter: Überprüfen Sie die API-Dokumentation auf erforderliche Felder
  3. Ungültige Marktplatz-ID: Verwenden Sie korrekte IDs (z. B. ATVPDKIKX0DER für die USA)
  4. 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:

  1. Länger warten – einige Berichte dauern 15-30 Minuten
  2. Überprüfen Sie, ob der Berichtstyp für Ihr Konto verfügbar ist
  3. Stellen Sie sicher, dass der Datumsbereich nicht zu groß ist (versuchen Sie kleinere Bereiche)
  4. Rufen Sie den Berichtsstatus alle 30 Sekunden ab, nicht kontinuierlich
  5. Einige Berichtstypen erfordern spezifische Berechtigungen

Problem: Benachrichtigungen kommen nicht an

Symptome: Abonnements wurden erstellt, aber es werden keine Benachrichtigungen empfangen.

Diagnose:

  1. Überprüfen Sie den Abonnementstatus über die API
  2. Stellen Sie sicher, dass die SNS-Topic-Richtlinie Amazon SES zulässt
  3. Bestätigen Sie, dass die Endpunkt-URL öffentlich zugänglich ist
  4. Überprüfen Sie die CloudWatch-Protokolle auf Zustellversuche

Lösungen:

  1. Stellen Sie sicher, dass das SNS-Topic die korrekte Ressourcenrichtlinie besitzt
  2. Überprüfen Sie den HTTPS-Endpunkt mit einem gültigen SSL-Zertifikat
  3. Geben Sie innerhalb von 30 Sekunden für alle Benachrichtigungen einen 200 OK-Status zurück
  4. Bestätigen Sie automatisch SubscriptionConfirmation-Nachrichten

Checkliste für die Produktionsbereitstellung

Bevor Sie live gehen:

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:

Implementierungsfluss:

  1. SNS-Benachrichtigung wird bei InventoryLevels-Ereignis ausgelöst
  2. Zentrales System berechnet neue Mengen
  3. Ratenbegrenzte API-Aufrufe aktualisieren jeden Marktplatz
  4. Bestätigung wird in die Audit-Datenbank protokolliert

Automatisierte Auftragsabwicklung

Ein Drittanbieter-Logistikdienstleister automatisiert die Auftragsabwicklung:

Wichtige Integrationspunkte:

Analyse-Dashboard

Ein Analyse-Tool für Verkäufer aggregiert Daten aus über 500 Verkäuferkonten:

Über die SP-API gesammelte Daten:

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:

Button

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.

Praktizieren Sie API Design-First in Apidog

Entdecken Sie eine einfachere Möglichkeit, APIs zu erstellen und zu nutzen