name: eBay Trading API Skill description: Create, manage, and research eBay listings for trading cards and collectibles.
eBay Trading API Skill
Create, manage, and research eBay listings for trading cards and collectibles.
When to Use
Use this skill when:
- Creating eBay listings from photos or item descriptions
- Looking up sold prices (comps) for pricing decisions
- Managing existing listings (revise, end)
- Building photo-to-listing automation workflows
Quick Start
Create a Listing
cd ~/clawd/ebay && python3 trading_api.py --create
Verify Without Listing (Dry Run)
cd ~/clawd/ebay && python3 trading_api.py
Check Sold Comps
cd ~/clawd/ebay && python3 comps.py "2024 Topps Chrome Mike Trout"
API Calls Available
| Call | Purpose | Script |
|---|---|---|
AddItem |
Create new listing | trading_api.py |
VerifyAddItem |
Validate without listing | trading_api.py |
ReviseItem |
Edit existing listing | revise.py (TODO) |
EndItem |
End/delete listing | end.py (TODO) |
GetItem |
Fetch listing details | get_item.py (TODO) |
findCompletedItems |
Sold price research | comps.py ✅ |
Card Conditions
Ungraded Cards (Condition ID: 4000)
| Condition | Descriptor ID |
|---|---|
| Near Mint or Better | 400010 |
| Excellent | 400011 |
| Very Good | 400012 |
| Poor | 400013 |
Graded Cards (Condition ID: 2750)
Supported graders: PSA, BGS, SGC, CGC, CSG, BVG, BCCG, KSA, GMA, HGA
Grades: 10, 9.5, 9, 8.5, 8, 7.5, 7, 6.5, 6, 5.5, 5, 4.5, 4, 3.5, 3, 2.5, 2, 1.5, 1, Authentic
Configuration
Required Environment Variables
Set in ~/.env.ebay or export directly:
EBAY_DEV_ID=your-dev-id
EBAY_APP_ID=your-app-id
EBAY_CERT_ID=your-cert-id
OAuth Tokens
Stored in ~/clawd/ebay/.tokens.json (auto-managed):
{
"access_token": "v^1.1#i^1#...",
"refresh_token": "v^1.1#i^1#...",
"expires_at": 1706644800
}
Run oauth_setup.py to initialize tokens, or refresh_token.py to refresh expired tokens.
Usage Examples
Python: Create Sports Card Listing
from trading_api import load_credentials, create_sports_card_listing
creds = load_credentials()
card_info = {
"title": "2024 Topps Chrome Mike Trout #1 Refractor",
"player": "Mike Trout",
"year": "2024",
"set_name": "Topps Chrome",
"card_number": "1",
"parallel": "Refractor",
"sport": "Baseball",
"manufacturer": "Topps",
"condition": "Near Mint or Better",
"graded": False
}
item_id = create_sports_card_listing(creds, card_info, price="29.99")
print(f"Listed: https://www.ebay.com/itm/{item_id}")
Python: Graded Card
card_info = {
"title": "2020 Panini Prizm LaMelo Ball RC PSA 10",
"player": "LaMelo Ball",
"year": "2020",
"set_name": "Panini Prizm",
"card_number": "278",
"sport": "Basketball",
"manufacturer": "Panini",
"graded": True,
"grader": "PSA",
"grade": "10",
"cert_number": "12345678"
}
item_id = create_sports_card_listing(creds, card_info, price="199.99")
Rate Limits
| API | Daily Limit | Reset Time |
|---|---|---|
| Trading API | 5,000 calls | Midnight PT |
| Finding API | 5,000 calls | Midnight PT |
Best practices:
- Use
VerifyAddItemfor testing (counts toward limit) - Implement exponential backoff on 503 errors
- Cache comp results to reduce Finding API calls
Troubleshooting
| Error | Cause | Fix |
|---|---|---|
Auth token is hard expired |
Access token expired (2hr) | Run oauth_setup.py |
Invalid refresh token |
Refresh token expired (18mo) | Full OAuth re-auth via oauth_setup.py |
exceeded the number of times |
eBay rate limited | Wait 1hr or check eBay developer dashboard |
Invalid App ID |
Wrong credentials | Check .env.ebay has EBAY_PROD_APP_ID |
Category not found |
Bad category ID | Use category names: basketball, baseball |
Missing item specifics |
Required fields empty | Add player, year, set, card_number |
No items found |
Too specific query | Broaden search terms |
Connection timeout |
eBay API slow | Retry in 30 seconds |
503 Service Unavailable |
API overloaded | Wait and retry with backoff |
Security Notes
🔑 Token Management
- Tokens stored in
.tokens.json— ensure 600 permissions:chmod 600 .tokens.json - Access tokens expire after 2 hours (auto-refresh via refresh_token)
- Refresh tokens expire after 18 months — calendar reminder recommended
- If refresh fails, re-run
oauth_setup.pyto re-authenticate
🔒 Credential Safety
- Never commit
.tokens.jsonor.env.ebayto git - Add to
.gitignore:.tokens.json,.env.ebay,*.log - Use environment variables, not hardcoded values
- Rotate tokens immediately if exposed
- API credentials (Dev/App/Cert IDs) are not secret but treat as private
✅ Input Validation
- All user input is HTML-escaped via
html.escape()before API calls - Titles limited to 80 characters (eBay max)
- Description wrapped in CDATA to prevent XML injection
- Card numbers, grades sanitized to alphanumeric
📋 Audit Trail
- Failed listings logged to
~/clawd/ebay/errors.log - Successful listings logged with ItemID, timestamp, and price
- Keep logs for 90 days minimum (eBay dispute window)
🛡️ API Response Handling
- Never log full API responses (may contain PII)
- Mask ItemIDs in non-debug logs:
1234***789 - Sanitize error messages before displaying to users
- Strip buyer/seller info from any logged responses
Sandbox vs Production
Toggle with sandbox parameter:
# Sandbox (testing)
response = call_trading_api(creds, "AddItem", xml, sandbox=True)
# Production (real listings)
response = call_trading_api(creds, "AddItem", xml, sandbox=False)
Sandbox URL: https://api.sandbox.ebay.com/ws/api.dll
Production URL: https://api.ebay.com/ws/api.dll
File Structure
~/clawd/ebay/
├── .env.ebay # API credentials (gitignored)
├── .tokens.json # OAuth tokens (gitignored)
├── trading_api.py # Core Trading API wrapper
├── description_template.py # HTML listing templates
├── oauth_setup.py # Initial OAuth flow
├── exchange_token.py # Token refresh
├── create_listing.py # Inventory API approach
└── pending.json # Pending listings queue
TODO
-
comps.py— findCompletedItems wrapper for price research ✅ -
revise.py— ReviseItem for editing listings -
end.py— EndItem for ending listings -
upload.py— eBay Picture Services integration - Rate limiting with exponential backoff
- Structured error logging
Known Limitations
Rate Limits
- Finding API: ~5,000 calls/day (may be lower for new apps)
- Trading API: ~5,000 calls/day
- If rate limited,
comps.pyreturnsfallback: true— use manual pricing - Limits reset at midnight Pacific Time
- New apps may have stricter burst limits initially
Token Expiry
- Access tokens expire after ~2 hours (auto-refreshed)
- Refresh tokens last 18 months — set a calendar reminder!
- If refresh fails, re-run
oauth_setup.pyto re-authenticate
Finding API Requires Production Credentials
The Finding API (findCompletedItems) does not have a sandbox environment. You must use production eBay credentials to look up sold prices. Add EBAY_PROD_APP_ID to your .env.ebay file.
References
Skill created by Clawd 🐾 & Electron 🦞 for Text2List.app