π Send Location Messages
Share precise location coordinates with WhatsApp contacts using the Whatspie API with support for custom location names and interactive maps.
πΊοΈ Interactive Location Sharing
Send precise GPS coordinates with automatic map preview, custom location names, and one-tap navigation for recipients.
π Endpointβ
POST https://api.whatspie.com/messages
π Authenticationβ
Bearer token required with proper JSON content headers.
π Request Parametersβ
Parameter | Type | Required | Description |
---|---|---|---|
device | string | β | Your registered WhatsApp device number |
receiver | string | β | Recipient's phone number (international format) |
type | string | β | Message type: "location" for location messages |
params | object | β | Message parameters containing location data |
params.location | object | β | Location object with coordinates |
params.location.degreesLatitude | number | β | Location latitude coordinate (-90 to 90) |
params.location.degreesLongitude | number | β | Location longitude coordinate (-180 to 180) |
simulate_typing | integer | β | Show typing indicator: 1 (yes) or 0 (no) |
πΊοΈ Coordinate Systemβ
Whatspie API uses the WGS84 coordinate system (same as GPS):
π Request Examplesβ
Basic Location Messageβ
curl -X POST "https://api.whatspie.com/messages" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"device": "6281234567890",
"receiver": "6289876543210",
"type": "location",
"params": {
"location": {
"degreesLatitude": -6.2088,
"degreesLongitude": 106.8456
}
},
"simulate_typing": 1
}'
Location with Custom Nameβ
curl -X POST "https://api.whatspie.com/messages" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"device": "6281234567890",
"receiver": "6289876543210",
"type": "location",
"params": {
"location": {
"degreesLatitude": -6.2088,
"degreesLongitude": 106.8456
}
},
"simulate_typing": 1
}'
Business Locationβ
curl -X POST "https://api.whatspie.com/messages" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"device": "6281234567890",
"receiver": "6289876543210",
"type": "location",
"latitude": 37.7749,
"longitude": -122.4194,
"location_name": "π’ Our Office - 123 Business St, San Francisco, CA",
"simulate_typing": 1
}'
π Response Formatβ
Success Responseβ
{
"code": 200,
"message": "Location sent successfully",
"data": {
"id": "msg_location_12345",
"status": "pending",
"type": "location",
"coordinates": {
"latitude": -6.2088,
"longitude": 106.8456
},
"location_name": "Monas - National Monument Jakarta",
"timestamp": "2024-12-20T10:30:00Z"
}
}
Error Response - Invalid Coordinatesβ
{
"code": 400,
"message": "Invalid coordinates",
"error": "Latitude must be between -90 and 90, longitude must be between -180 and 180"
}
π Advanced Examplesβ
Location with Address Lookupβ
// Reverse geocoding to get address from coordinates
async function sendLocationWithAddress(token, device, receiver, latitude, longitude) {
try {
// Get address from coordinates (using a geocoding service)
const address = await reverseGeocode(latitude, longitude);
const locationName = `π ${address.name}\n${address.street}, ${address.city}`;
return await sendLocationMessage(
token,
device,
receiver,
latitude,
longitude,
locationName
);
} catch (error) {
// Fallback to coordinates only if address lookup fails
return await sendLocationMessage(token, device, receiver, latitude, longitude);
}
}
// Mock reverse geocoding function
async function reverseGeocode(lat, lng) {
// In real implementation, use Google Maps API, OpenStreetMap, etc.
return {
name: "Business Center",
street: "Jl. Sudirman No. 123",
city: "Jakarta"
};
}
Batch Location Sharingβ
async function sendMultipleLocations(token, device, receiver, locations) {
const results = [];
for (const location of locations) {
try {
const result = await sendLocationMessage(
token,
device,
receiver,
location.latitude,
location.longitude,
location.name
);
results.push({
location: location.name,
success: true,
messageId: result.data.id
});
// Delay between messages to avoid rate limiting
await new Promise(resolve => setTimeout(resolve, 2000));
} catch (error) {
results.push({
location: location.name,
success: false,
error: error.message
});
}
}
return results;
}
// Usage
const touristSpots = [
{ name: 'πΏ Monas Jakarta', latitude: -6.1751, longitude: 106.8650 },
{ name: 'ποΈ National Museum', latitude: -6.1717, longitude: 106.8219 },
{ name: 'π Ancol Beach', latitude: -6.1260, longitude: 106.8421 }
];
sendMultipleLocations('YOUR_API_TOKEN', '6281234567890', '6289876543210', touristSpots);
Location with Custom Map Previewβ
// Generate custom map URL for location preview
function generateMapPreview(latitude, longitude, zoom = 15) {
return `https://maps.googleapis.com/maps/api/staticmap?center=${latitude},${longitude}&zoom=${zoom}&size=400x300&maptype=roadmap&markers=color:red%7C${latitude},${longitude}&key=YOUR_MAPS_API_KEY`;
}
async function sendLocationWithPreview(token, device, receiver, latitude, longitude, locationName) {
// First send the location
const locationResult = await sendLocationMessage(
token,
device,
receiver,
latitude,
longitude,
locationName
);
// Then send a map preview image (optional)
const mapUrl = generateMapPreview(latitude, longitude);
const imageResult = await sendImageMessage(
token,
device,
receiver,
mapUrl,
'πΊοΈ Map Preview'
);
return {
location: locationResult,
preview: imageResult
};
}
π‘ Best Practicesβ
1. Coordinate Validationβ
function validateCoordinates(latitude, longitude) {
const lat = parseFloat(latitude);
const lng = parseFloat(longitude);
if (isNaN(lat) || lat < -90 || lat > 90) {
throw new Error('Invalid latitude. Must be between -90 and 90');
}
if (isNaN(lng) || lng < -180 || lng > 180) {
throw new Error('Invalid longitude. Must be between -180 and 180');
}
return { latitude: lat, longitude: lng };
}
2. Location Name Formattingβ
function formatLocationName(name, address = null, category = null) {
let formattedName = '';
// Add category emoji
const categoryEmojis = {
'restaurant': 'π½οΈ',
'hotel': 'π¨',
'office': 'π’',
'hospital': 'π₯',
'school': 'π«',
'shopping': 'ποΈ',
'gas_station': 'β½',
'bank': 'π¦'
};
if (category && categoryEmojis[category]) {
formattedName += categoryEmojis[category] + ' ';
} else {
formattedName += 'π ';
}
formattedName += name;
if (address) {
formattedName += '\n' + address;
}
return formattedName;
}
// Usage
const locationName = formatLocationName(
'Central Park Mall',
'Jl. Letjen S. Parman, Jakarta Barat',
'shopping'
);
// Result: "ποΈ Central Park Mall\nJl. Letjen S. Parman, Jakarta Barat"
3. Distance Calculationβ
function calculateDistance(lat1, lon1, lat2, lon2) {
const R = 6371; // Earth's radius in kilometers
const dLat = (lat2 - lat1) * Math.PI / 180;
const dLon = (lon2 - lon1) * Math.PI / 180;
const a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(lat1 * Math.PI / 180) * Math.cos(lat2 * Math.PI / 180) *
Math.sin(dLon / 2) * Math.sin(dLon / 2);
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
const distance = R * c; // Distance in kilometers
return Math.round(distance * 100) / 100; // Round to 2 decimal places
}
// Usage
const distance = calculateDistance(-6.2088, 106.8456, -6.1751, 106.8650);
console.log(`Distance: ${distance} km`);
π Common Locationsβ
Famous Landmarksβ
const landmarks = {
// Indonesia
monas: { lat: -6.1751, lng: 106.8650, name: 'πΏ Monas - National Monument' },
borobudur: { lat: -7.6079, lng: 110.2038, name: 'ποΈ Borobudur Temple' },
// International
eiffel_tower: { lat: 48.8584, lng: 2.2945, name: 'πΌ Eiffel Tower, Paris' },
statue_liberty: { lat: 40.6892, lng: -74.0445, name: 'π½ Statue of Liberty, NYC' },
big_ben: { lat: 51.4994, lng: -0.1245, name: 'π°οΈ Big Ben, London' }
};
// Send landmark location
await sendLocationMessage(
'YOUR_API_TOKEN',
'6281234567890',
'6289876543210',
landmarks.monas.lat,
landmarks.monas.lng,
landmarks.monas.name
);
β οΈ Limitationsβ
- Coordinate precision: Up to 6 decimal places for accuracy
- Location name: Maximum 100 characters
- Map providers: Location display depends on recipient's map app
- Real-time tracking: Static location only, no live tracking
- Offline access: Recipients need internet to view map details
π Related Endpointsβ
- Send Text Messages - For location descriptions
- Send Image Messages - For map screenshots
- Get Message Status - Check delivery status
πΊοΈ Map Integration Servicesβ
For enhanced location features, consider integrating:
- Google Maps API - Address lookup and static maps
- OpenStreetMap - Open source mapping
- Mapbox - Custom map styling
- Here Maps - Enterprise mapping solutions