API Documentation
Capture leads from your website forms directly into TradeSender using our REST API.
Authentication
All API requests require an API key passed in the X-API-Key header. You can create and manage API keys from your TradeSender dashboard.
curl -H "X-API-Key: ts_live_abc123..." \
https://app.tradesender.co.uk/api/v1/leadsNever expose your API key in client-side JavaScript. Always make API calls from your server or serverless functions.
Create Lead
/api/v1/leadsCreates a new lead in your TradeSender account. The request body is a discriminated union based on the type field. Choose the type that matches your form:
Request Body
| Name | Type | Required | Description |
|---|---|---|---|
type | string | Must be "quote_request" | |
name | string | Full name of the requester (max 255) | |
email | string | Valid email address | |
phone | string | Phone number (max 50) | |
message | string | Additional details (max 5000) | |
service | string | Requested service type (max 255) | |
address | object | Service address (see fields below) | |
└ line1 | string | Street address | |
└ line2 | string | Apt, suite, unit, etc. | |
└ city | string | City name | |
└ state | string | State or county | |
└ zipCode | string | Postal / ZIP code | |
└ country | string | Country name | |
timeframe | string | Preferred timeframe (max 100) | |
budgetRange | string | Budget range (max 100) | |
photos | string[] | Array of HTTPS photo URLs (max 10) |
Code Examples
curl -X POST https://app.tradesender.co.uk/api/v1/leads \
-H "Content-Type: application/json" \
-H "X-API-Key: ts_live_abc123..." \
-d '{
"type": "quote_request",
"name": "Jane Smith",
"email": "jane@example.com",
"phone": "+44 7700 900123",
"service": "Lawn Mowing",
"message": "Looking for a weekly mowing service for my front and back garden."
}'const response = await fetch("https://app.tradesender.co.uk/api/v1/leads", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-API-Key": process.env.TRADESENDER_API_KEY,
},
body: JSON.stringify({
type: "quote_request",
name: "Jane Smith",
email: "jane@example.com",
phone: "+44 7700 900123",
service: "Lawn Mowing",
message: "Looking for a weekly mowing service.",
}),
});
const lead = await response.json();
console.log(lead.id); // "a1b2c3d4-..."import requests
response = requests.post(
"https://app.tradesender.co.uk/api/v1/leads",
headers={
"Content-Type": "application/json",
"X-API-Key": "ts_live_abc123...",
},
json={
"type": "quote_request",
"name": "Jane Smith",
"email": "jane@example.com",
"phone": "+44 7700 900123",
"service": "Lawn Mowing",
"message": "Looking for a weekly mowing service.",
},
)
lead = response.json()
print(lead["id"]) # "a1b2c3d4-..."Responses
201Lead Created
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"type": "quote_request",
"name": "Jane Smith",
"email": "jane@example.com",
"phone": "+44 7700 900123",
"createdAt": "2025-06-15T10:30:00.000Z"
}Error Responses
401Unauthorized
Missing or invalid API key. Check your X-API-Key header.
403Forbidden
API key lacks the required leads:write scope, or has been revoked.
422Validation Error
Request body failed validation. The response includes field-level details:
{
"error": "Validation failed",
"details": [
{
"path": ["email"],
"message": "Invalid email"
}
]
}429Too Many Requests
Rate limit exceeded. Wait until the X-RateLimit-Reset time before retrying.
Rate Limiting
Every response includes rate limit headers so you can track your usage:
| Name | Type | Required | Description |
|---|---|---|---|
X-RateLimit-Limit | number | Maximum requests per window | |
X-RateLimit-Remaining | number | Requests remaining in current window | |
X-RateLimit-Reset | number | Unix timestamp when the window resets |
Read the X-RateLimit-Reset header and wait until that timestamp before retrying. Implement exponential backoff for the best reliability.
Ready to integrate?
Create your free TradeSender account and generate an API key to get started.
Get Started Free