A fully typed TypeScript SDK, REST API, and open source codebase. Build integrations for the school marketplace.
Add the Trade Buddy SDK to your project with npm or yarn.
Sign in with email and password to get a session token.
Query the marketplace for products, donations, or wanted items.
Post a new item to the marketplace programmatically.
// Step 1: Install // Run in your terminal: npm install @tradebuddy/sdk // or with yarn: yarn add @tradebuddy/sdk // TypeScript types are included out of the box. // No @types package needed.
import { TradeBuddy } from '@tradebuddy/sdk'; // Create a client instance const client = new TradeBuddy(); // Authenticate with email and password const session = await client.signIn({ email: 'jane@school.edu', password: 'your-password', }); console.log(session.user.name); // "Jane Doe" console.log(session.token); // "eyJhbG..."
// Fetch all listings from the marketplace const listings = await client.getListings(); // Each listing is fully typed listings.forEach((item: Listing) => { console.log(item.title); // "School Blazer" console.log(item.type); // "Sell" | "Donate" | "Wanted" console.log(item.price); // 25 console.log(item.category); // "School Uniform" }); // Filter by type const donations = listings.filter( l => l.type === 'Donate' );
// Create a new listing const newListing = await client.createListing({ title: 'Graphing Calculator', type: 'Sell', price: 35, category: 'Electronics', condition: 'Like New', description: 'TI-84 Plus, barely used', }); console.log(newListing.id); // "sell_42" // Delete your account (careful!) await client.deleteAccount();
| Parameter | Type | Description |
|---|---|---|
| name required | string | Full name of the user |
| email required | string | User's email address |
| password required | string | Account password |
import { TradeBuddy } from '@tradebuddy/sdk'; const client = new TradeBuddy(); const session = await client.signUp({ name: 'Jane Doe', email: 'jane@school.edu', password: 'secure-password', }); console.log(session.user); // { id: 42, name: "Jane Doe", ... } console.log(session.token); // Bearer token
curl -X POST https://mytradebuddy.com/api/auth.php?action=signup \ -H "Content-Type: application/json" \ -d '{ "name": "Jane Doe", "email": "jane@school.edu", "password": "secure-password" }'
{
"success": true,
"user": {
"id": 42,
"name": "Jane Doe",
"email": "jane@school.edu"
},
"token": "eyJhbGciOiJIUzI1NiJ9..."
}| Parameter | Type | Description |
|---|---|---|
| email required | string | Registered email address |
| password required | string | Account password |
const session = await client.signIn({ email: 'jane@school.edu', password: 'secure-password', }); // Session is now active console.log(session.user.name); // "Jane Doe"
curl -X POST https://mytradebuddy.com/api/auth.php?action=login \ -H "Content-Type: application/json" \ -d '{ "email": "jane@school.edu", "password": "secure-password" }'
{
"success": true,
"user": { "id": 42, "name": "Jane Doe", "email": "jane@school.edu" },
"token": "eyJhbGciOiJIUzI1NiJ9..."
}await client.signOut(); // Token is now invalidated on the server
curl -X POST https://mytradebuddy.com/api/auth.php?action=logout \
-H "Authorization: Bearer YOUR_TOKEN"// Permanently deletes account + all listings await client.deleteAccount(); // All user data removed from database
curl -X POST https://mytradebuddy.com/api/account.php?action=delete \
-H "Authorization: Bearer YOUR_TOKEN"{
"success": true,
"message": "Account deleted successfully"
}const listings = await client.getListings(); listings.forEach((item: Listing) => { console.log(`${item.title} — $${item.price}`); console.log(`${item.category} | ${item.condition}`); console.log(`Seller: ${item.sellerName}`); });
curl https://mytradebuddy.com/api/listings.php
{
"success": true,
"listings": [
{
"id": "sell_17",
"type": "Sell",
"title": "Sixth Form Uniform",
"price": 40,
"category": "School Uniform",
"condition": "Good",
"sellerName": "Arhan Harchandani",
"createdAt": 1773280792000
}
]
}| Parameter | Type | Description |
|---|---|---|
| title required | string | Item title |
| type required | "Sell" | "Donate" | "Wanted" | Listing type |
| price optional | number | Price (Sell only) |
| category required | string | One of 12 categories |
| condition required | string | New, Like New, Good, Fair |
| description optional | string | Additional details |
const listing = await client.createListing({ title: 'Graphing Calculator', type: 'Sell', price: 35, category: 'Electronics', condition: 'Like New', description: 'TI-84 Plus, barely used.', }); console.log(listing.id); // "sell_42"
curl -X POST https://mytradebuddy.com/api/listings.php \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "title": "Graphing Calculator", "type": "Sell", "price": 35, "category": "Electronics", "condition": "Like New" }'
{
"success": true,
"id": "sell_42"
}-- Authentication Tests test "login with invalid credentials returns failure": response is await postJSON("{api_url}/auth.php?action=login", { email: "fake@nonexistent.com", password: "wrongpassword123" }) expect response.success is no -- Listings Tests test "each listing has a valid type": data is await fetchJSON("{api_url}/listings.php") for each item in data.listings: expect isValidType(item.type) is yes -- Data Integrity test "no duplicate listing IDs": data is await fetchJSON("{api_url}/listings.php") ids is map_list(data.listings, with i: i.id) expect length(unique(ids)) is length(ids)
interface TradeBuddyConfig { baseUrl?: string; // default: "https://mytradebuddy.com/api" token?: string; // optional: resume a session } interface User { id: number; name: string; email: string; } interface Session { user: User; token: string; } interface Listing { id: string; type: 'Sell' | 'Donate' | 'Wanted'; title: string; price: number; category: Category; condition: Condition; description?: string; imageUri?: string; sellerName: string; sellerEmail: string; createdAt: number; } type Category = | 'Books' | 'Electronics' | 'Clothing & Accessories' | 'School Uniform' | 'Sports Equipment' | 'Toys' | 'Video Games' | 'Board Games' | 'Furniture' | 'Kitchen Items' | 'Household Items' | 'Jewelry & Watches'; type Condition = 'New' | 'Like New' | 'Good' | 'Fair';
TypeScript types for every request and response
Uses native fetch — Node, Deno, Bun, browsers
Handles Bearer tokens automatically after sign in
Import only what you need — minimal bundle
// POST to your endpoint { "event": "listing.created", "timestamp": 1711843200000, "data": { "id": "sell_42", "type": "Sell", "title": "Graphing Calculator", "price": 35, "category": "Electronics", "condition": "Like New", "sellerName": "Jane Doe", "sellerEmail": "jane@school.edu" } }
import { TradeBuddy } from '@tradebuddy/sdk'; const client = new TradeBuddy(); await client.signIn({ email, password }); // Register a webhook endpoint const webhook = await client.createWebhook({ url: 'https://yourapp.com/webhooks/tradebuddy', events: [ 'listing.created', 'listing.sold', 'user.created', ], secret: 'whsec_your_secret_here', }); console.log(webhook.id); // "wh_abc123"
import crypto from 'crypto'; // Verify webhook signature in your handler function verifyWebhook(body: string, signature: string, secret: string): boolean { const expected = crypto .createHmac('sha256', secret) .update(body) .digest('hex'); return crypto.timingSafeEqual( Buffer.from(signature), Buffer.from(expected), ); } // Express handler example app.post('/webhooks/tradebuddy', (req, res) => { const sig = req.headers['x-tradebuddy-signature']; if (!verifyWebhook(req.body, sig, 'whsec_...')) { return res.status(401).send('Invalid signature'); } const event = JSON.parse(req.body); console.log(event.event); // "listing.created" res.status(200).send('ok'); });
Every payload is signed with SHA-256 for verification
Subscribe only to the events you care about
Failed deliveries are retried with exponential backoff
View request/response history for every delivery attempt
Full access — listings, users, webhooks
tb_live_sk_7f3a...
Secret
Sandbox — no real data affected
tb_test_sk_9c2b...
Test
Read-only — listings and categories
tb_live_pk_4d1e...
Public
import { TradeBuddy } from '@tradebuddy/sdk'; // Authenticate with an API key instead of email/password const client = new TradeBuddy({ apiKey: 'tb_live_sk_7f3a...', }); // All methods work the same way const listings = await client.getListings(); // Public keys are read-only const publicClient = new TradeBuddy({ apiKey: 'tb_live_pk_4d1e...', }); const items = await publicClient.getListings(); // ✓ works // publicClient.createListing(...) // ✗ 403 Forbidden
# Use API key in the Authorization header curl https://mytradebuddy.com/api/listings.php \ -H "Authorization: Bearer tb_live_sk_7f3a..." # Check your rate limit status # Response headers include: # X-RateLimit-Limit: 1000 # X-RateLimit-Remaining: 994 # X-RateLimit-Reset: 1711843260 # Create a listing with a production key curl -X POST https://mytradebuddy.com/api/listings.php \ -H "Authorization: Bearer tb_live_sk_7f3a..." \ -H "Content-Type: application/json" \ -d '{ "title": "School Blazer", "type": "Sell", "price": 25, "category": "School Uniform", "condition": "Good" }'
// Create a new API key const key = await client.createApiKey({ name: 'My Integration', type: 'secret', // 'secret' | 'public' scopes: ['listings:read', 'listings:write'], }); console.log(key.key); // "tb_live_sk_..." — shown once! // List all your API keys const keys = await client.listApiKeys(); keys.forEach(k => { console.log(k.name); // "My Integration" console.log(k.lastUsed); // "2026-03-28T14:30:00Z" console.log(k.requests); // 4832 }); // Revoke a key await client.revokeApiKey('key_abc123');
listings:readView all marketplace listingslistings:writeCreate, update, and delete listingsusers:readView user profilesusers:writeManage user accountswebhooks:manageCreate and delete webhook subscriptionsanalytics:readView usage statistics and metrics~ npx tradebuddy Trade Buddy CLI v1.0.0 Browse listings, post items, and manage your account. Quick start: $ tradebuddy login Sign in to your account $ tradebuddy browse Browse all listings $ tradebuddy browse -c Books Browse books only $ tradebuddy post Post an item $ tradebuddy categories List all 13 categories Run tradebuddy --help for all commands.
Authenticate with your Trade Buddy account via interactive prompts.
Search and filter listings by category, keyword, or type with -c and -s flags.
List products, donations, or wanted items with an interactive step-by-step flow.
View all 13 marketplace categories at a glance.
Fully typed client for the Trade Buddy API. Install with npm, get autocomplete and type safety out of the box.
Subscribe to real-time events — new listings, sales, account changes. Get HTTP POST notifications to your endpoint.
Dedicated API keys for third-party apps. Rate limiting, usage analytics, and scoped permissions per key.
Drop a <script> tag on any school website to display Trade Buddy listings. Customizable themes and filters.
Interact with Trade Buddy from your terminal. Browse listings, post items, manage your account with npx tradebuddy.
A beginner-friendly programming language that reads like English and compiles to JavaScript. quill.tradebuddy.dev
Real-time API uptime monitoring at status.tradebuddy.dev. Incident history and response time metrics.
Track every API change with versioned release notes. Never be surprised by breaking changes.
Server-rendered PHP with MySQL. 12 category pages, admin panel, messaging, donations, wanted items.
Cross-platform React Native app built with Expo. Shares the same database and user accounts as the website.
PHP endpoints with Bearer token auth. Powers the mobile app and the TypeScript SDK.
Shared MySQL database. Single source of truth for users, listings, messages, and sessions.
Multi-purpose TypeScript Discord bot for the Trade Buddy community server. Moderation, notifications, and more.
Clone the app or SDK repository and set up your local dev environment.
git clone https://github.com/tradebuddyhq/app.gitCheck out open issues. Look for good first issue labels to get started.
gh issue list --repo tradebuddyhq/appMake your changes, test locally, and open a pull request. We review within 48 hours.
git checkout -b feature/your-featureGet support with Quill, the SDK, and all Trade Buddy projects. Chat with the community and the dev team.
Join our DiscordInstall the SDK, explore the API, and help make school essentials accessible for every family.