DEV Community

Cover image for How to Use eBay APIs?
Wanda
Wanda

Posted on • Originally published at apidog.com

How to Use eBay APIs?

TL;DR

eBay APIs allow you to programmatically manage inventory, listings, orders, and payments. Authenticate using OAuth 2.0, utilize the api.ebay.com/sell endpoints, and always implement rate-limit handling. For robust testing, use Apidog to validate listing payloads, test order processing, and ensure your integration gracefully handles API limits.

Try Apidog today

Introduction

eBay connects buyers and sellers globally. The API is designed for sellers to automate inventory management, create bulk listings, process orders, manage shipping, and handle returns. The API scales from single sellers to large enterprises.

Main API areas:

  • Inventory API: Manage product inventory
  • Listing API: Create and manage item listings
  • Order API: Process orders and shipments
  • Fulfillment API: Handle shipping and tracking
  • Analytics API: Pull sales reports

💡 Tip: If you’re building eBay integrations, Apidog lets you test listing creation, validate order responses, and ensure your integration handles rate limits and errors correctly.

Test eBay APIs with Apidog for free.

By the end of this guide, you’ll know how to:

  • Authenticate with eBay OAuth 2.0
  • Create and manage inventory items
  • Publish listings
  • Process orders and shipments
  • Handle returns and refunds
  • Test your integration with Apidog

Authentication with OAuth 2.0

eBay uses OAuth 2.0 for API authentication. Here’s how to get started:

eBay App Creation

Create an application

  1. Go to developers.ebay.com
  2. Register for a developer account.
  3. Create an application in the Developer Console.
  4. Obtain your App ID (Client ID) and Cert ID (Client Secret).

OAuth flow

Step 1: User Authorization

https://auth.ebay.com/oauth2/authorize?
  client_id=YOUR_APP_ID&
  response_type=code&
  redirect_uri=YOUR_SIGNIN_REDIRECT_URI&
  scope=https://api.ebay.com/oauth/api_scope/sell.inventory
Enter fullscreen mode Exit fullscreen mode

Step 2: Get Authorization Code

After user authorization, your redirect URI receives a code parameter.

Step 3: Exchange Code for Tokens

const response = await fetch('https://api.ebay.com/identity/v1/oauth2/token', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded',
    'Authorization': 'Basic ' + Buffer.from(APP_ID + ':' + CERT_ID).toString('base64')
  },
  body: new URLSearchParams({
    grant_type: 'authorization_code',
    code: AUTHORIZATION_CODE,
    redirect_uri: 'YOUR_SIGNIN_REDIRECT_URI'
  })
})

const { access_token, refresh_token, expires_in } = await response.json()
Enter fullscreen mode Exit fullscreen mode

Required OAuth Scopes

  • https://api.ebay.com/oauth/api_scope/sell.inventory - Inventory management
  • https://api.ebay.com/oauth/api_scope/sell.listings - Listings
  • https://api.ebay.com/oauth/api_scope/sell.orders - Orders
  • https://api.ebay.com/oauth/api_scope/sell.fulfillment - Fulfillment
  • https://api.ebay.com/oauth/api_scope/sell.account - Account management

Inventory Management

Inventory items represent the products you sell.

Create Inventory Location

curl -X POST "https://api.ebay.com/sell/inventory/v1/location_inventory_location" \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "locationId": "WAREHOUSE_1",
    "name": "Main Warehouse",
    "address": {
      "addressLine1": "123 Main St",
      "city": "San Jose",
      "stateOrProvince": "CA",
      "postalCode": "95101",
      "countryCode": "US"
    }
  }'
Enter fullscreen mode Exit fullscreen mode

Create an Inventory Item

curl -X POST "https://api.ebay.com/sell/inventory/v1/inventory_item" \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "product": {
      "title": "Vintage Leather Messenger Bag",
      "description": "Genuine leather messenger bag, perfect for work or school.",
      "aspects": {
        "Brand": ["Vintage"],
        "Material": ["Leather"],
        "Color": ["Brown"]
      },
      "imageUrls": [
        "https://example.com/images/bag1.jpg",
        "https://example.com/images/bag2.jpg"
      ]
    },
    "condition": "USED_GOOD",
    "conditionNotes": "Minor wear on corners",
    "availability": {
      "shipToLocationAvailability": {
        "quantity": 25
      }
    }
  }'
Enter fullscreen mode Exit fullscreen mode

Update Inventory

curl -X PUT "https://api.ebay.com/sell/inventory/v1/inventory_item/SKU123" \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "availability": {
      "shipToLocationAvailability": {
        "quantity": 30
      }
    }
  }'
Enter fullscreen mode Exit fullscreen mode

Get Inventory Item

curl -X GET "https://api.ebay.com/sell/inventory/v1/inventory_item/SKU123" \
  -H "Authorization: Bearer ACCESS_TOKEN"
Enter fullscreen mode Exit fullscreen mode

Listing Items

Create an Offer

curl -X POST "https://api.ebay.com/sell/inventory/v1/offer" \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "sku": "SKU123",
    "marketplaceId": "EBAY_US",
    "format": "FIXED_PRICE",
    "product": {
      "title": "Vintage Leather Messenger Bag"
    },
    "pricingSummary": {
      "price": {
        "currency": "USD",
        "value": "89.99"
      }
    },
    "listing": {
      "listingDuration": "GTC",
      "listingType": "CLASSIC"
    },
    " fulfillment": {
      "shippingProfileId": "SHIPPING_PROFILE_ID",
      " fulfillmentPolicyId": "FULFILLMENT_POLICY_ID",
      "paymentPolicyId": "PAYMENT_POLICY_ID"
    }
  }'
Enter fullscreen mode Exit fullscreen mode

Key fields:

  • sku: Your inventory SKU
  • marketplaceId: e.g., EBAY_US, EBAY_UK, EBAY_DE
  • format: FIXED_PRICE or AUCTION
  • listingDuration: GTC (Good Til Canceled) or other
  • price: Asking price

Publish the Offer

curl -X POST "https://api.ebay.com/sell/inventory/v1/offer/OFFER_ID/publish" \
  -H "Authorization: Bearer ACCESS_TOKEN"
Enter fullscreen mode Exit fullscreen mode

Withdraw a Listing

curl -X POST "https://api.ebay.com/sell/inventory/v1/offer/OFFER_ID/withdraw" \
  -H "Authorization: Bearer ACCESS_TOKEN"
Enter fullscreen mode Exit fullscreen mode

Order Management

Get Orders

curl -X GET "https://api.ebay.com/sell/fulfillment/v1/order?orderIds=ORDER_ID_1,ORDER_ID_2" \
  -H "Authorization: Bearer ACCESS_TOKEN"
Enter fullscreen mode Exit fullscreen mode

Filter by date:

curl -X GET "https://api.ebay.com/sell/fulfillment/v1/order?filter=creation_date_range:from:2026-01-01T00:00:00Z,to:2026-03-24T00:00:00Z" \
  -H "Authorization: Bearer ACCESS_TOKEN"
Enter fullscreen mode Exit fullscreen mode

Get Order Details

curl -X GET "https://api.ebay.com/sell/fulfillment/v1/order/ORDER_ID" \
  -H "Authorization: Bearer ACCESS_TOKEN"
Enter fullscreen mode Exit fullscreen mode

Order response example:

{
  "orderId": "12-34567-89012",
  "orderPaymentStatus": "PAID",
  "pricingSummary": {
    "total": {
      "currency": "USD",
      "value": "94.99"
    }
  },
  "fulfillmentStartInstructions": [
    {
      "shippingStep": {
        "shipTo": {
          "fullName": "John Doe",
          "contactAddress": {
            "addressLine1": "123 Main St",
            "city": "Anytown",
            "stateOrProvince": "CA",
            "postalCode": "12345",
            "countryCode": "US"
          }
        }
      }
    }
  ],
  "lineItems": [
    {
      "lineItemId": "LINE_ITEM_ID",
      "sku": "SKU123",
      "quantity": 1,
      "title": "Vintage Leather Messenger Bag",
      "lineItemCost": {
        "currency": "USD",
        "value": "89.99"
      }
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

Shipping and Fulfillment

Create Shipping Label

curl -X POST "https://api.ebay.com/sell/fulfillment/v1/order/ORDER_ID/shipping_fulfillment" \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "lineItems": [
      {
        "lineItemId": "LINE_ITEM_ID",
        "quantity": 1
      }
    ],
    "shippingStep": {
      "shipFrom": {
        "fullName": "Your Name",
        "companyName": "Your Company",
        "contactAddress": {
          "addressLine1": "456 Warehouse Rd",
          "city": "San Jose",
          "stateOrProvince": "CA",
          "postalCode": "95101",
          "countryCode": "US"
        }
      }
    },
    "shippingCarrierCode": "USPS",
    "shippingMethodCode": "PRIORITY_MAIL",
    "trackingNumber": "9400111899223056789012"
  }'
Enter fullscreen mode Exit fullscreen mode

Carriers supported:

  • USPS
  • UPS
  • FedEx
  • DHL

Returns Management

Get Return Details

curl -X GET "https://api.ebay.com/sell/fulfillment/v1/return/RETURN_ID" \
  -H "Authorization: Bearer ACCESS_TOKEN"
Enter fullscreen mode Exit fullscreen mode

Process a Return

curl -X POST "https://api.ebay.com/sell/fulfillment/v1/return/RETURN_ID/decide" \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "decision": "ACCEPT",
    "shipment": {
      "carrierId": "CARRIER_ID",
      "trackingNumber": "TRACKING_NUMBER"
    }
  }'
Enter fullscreen mode Exit fullscreen mode

Rate Limits and Handling

eBay enforces API rate limits. Always check these response headers:

  • X-RateLimit-Limit: Max allowed requests
  • X-RateLimit-Remaining: Requests left in current window
  • X-RateLimit-Reset: Unix timestamp when limits reset

Sample rate-limit handling:

async function makeEbayRequest(url, options, retries = 3) {
  for (let i = 0; i < retries; i++) {
    const response = await fetch(url, options)

    const remaining = response.headers.get('X-RateLimit-Remaining')
    if (remaining && parseInt(remaining) < 10) {
      console.warn('Rate limit low:', remaining)
    }

    if (response.status === 429) {
      const resetTime = response.headers.get('X-RateLimit-Reset')
      const waitTime = (parseInt(resetTime) - Date.now() / 1000) * 1000
      await sleep(waitTime)
      continue
    }

    return response
  }
  throw new Error('Rate limited')
}
Enter fullscreen mode Exit fullscreen mode

Testing with Apidog

eBay APIs are production-critical—test thoroughly before going live.

Apidog Testing

1. Environment Setup

EBAY_APP_ID: your_app_id
EBAY_CERT_ID: your_cert_id
EBAY_ACCESS_TOKEN: stored_token
EBAY_REFRESH_TOKEN: stored_refresh
EBAY_MARKETPLACE_ID: EBAY_US
BASE_URL: https://api.ebay.com
Enter fullscreen mode Exit fullscreen mode

2. Validate Listing Payloads

pm.test('Listing has required fields', () => {
  const requestBody = JSON.parse(pm.request.body.raw)
  pm.expect(requestBody).to.have.property('sku')
  pm.expect(requestBody).to.have.property('marketplaceId')
  pm.expect(requestBody.pricingSummary).to.have.property('price')
})

pm.test('Price is valid', () => {
  const requestBody = JSON.parse(pm.request.body.raw)
  const price = parseFloat(requestBody.pricingSummary.price.value)
  pm.expect(price).to.be.above(0)
})
Enter fullscreen mode Exit fullscreen mode

3. Test Order Processing

pm.test('Order response is valid', () => {
  const response = pm.response.json()
  pm.expect(response).to.have.property('orderId')
  pm.expect(response.orderPaymentStatus).to.eql('PAID')
  pm.expect(response.lineItems).to.be.an('array')
})
Enter fullscreen mode Exit fullscreen mode

Test eBay APIs with Apidog for free.


Common Errors and Fixes

401 Unauthorized

Cause: Token expired or invalid.

Fix: Use refresh token to get a new access token.

const response = await fetch('https://api.ebay.com/identity/v1/oauth2/token', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded',
    'Authorization': 'Basic ' + Buffer.from(APP_ID + ':' + CERT_ID).toString('base64')
  },
  body: new URLSearchParams({
    grant_type: 'refresh_token',
    refresh_token: storedRefreshToken
  })
})
Enter fullscreen mode Exit fullscreen mode

10002: Api error – Invalid access token

Cause: Access token expired.

Fix: Refresh the token.

21916684: Item does not exist

Cause: Trying to update a SKU that wasn’t created.

Fix: Create the inventory item first, then create the offer.

10003: Invalid sku

Cause: SKU format invalid.

Fix: SKUs must be unique and can only contain alphanumeric characters, hyphens, and underscores.

Rate limit (429)

Cause: Too many requests.

Fix: Implement exponential backoff. Limits vary by endpoint.


Alternatives and Comparisons

Feature eBay Amazon SP-API Etsy
Inventory API ✓ ✓ Limited
Listing API ✓ ✓ ✓
Order API ✓ ✓ ✓
Fulfillment API ✓ ✓ Limited
Free tier Developer program Limited Limited
API complexity Medium High Low

eBay’s API is more approachable than Amazon’s but less feature-rich. Etsy’s API is simplest but limited for large sellers.


Real-world Use Cases

  • Multi-channel selling: Sync inventory across eBay, Amazon, and your own site. When an item sells on one channel, update quantity everywhere.
  • Automated repricing: Monitor competitors and adjust prices via API to stay competitive.
  • Bulk listing: Create thousands of listings with CSV uploads and bulk API operations.

Conclusion

You should now be able to:

  • Authenticate with OAuth 2.0 using app credentials
  • Manage inventory with SKUs
  • Create and publish listings
  • Process orders and shipments
  • Handle returns
  • Test integrations with Apidog before production

Your next steps:

  1. Apply for the eBay Developers Program
  2. Create an application and obtain credentials
  3. Implement the OAuth flow
  4. Create your first inventory item
  5. Publish a test listing

Test eBay APIs with Apidog for free.


FAQ

Do I need a business account to use APIs?

Yes. eBay APIs are for verified sellers. Sign up for a seller account and complete verification.

What’s the difference between inventory and offers?

Inventory is product information (title, description, images). Offers link inventory to a marketplace with pricing and fulfillment details. Multiple offers can reference the same inventory.

How long do listings stay active?

Listings with GTC (Good Til Canceled) remain active until withdrawn or sold out.

Can I sell internationally via API?

Yes. Set marketplaceId to values like EBAY_US, EBAY_UK, EBAY_DE, etc. You must comply with each marketplace’s requirements.

What’s the API rate limit?

Limits vary by endpoint and account level. Check response headers for your current limits.

How do I get shipping labels?

eBay provides discounted shipping labels through the Fulfillment API. Create the shipment, and eBay generates a label.

Top comments (0)