This guide explains how to use the Bump service APIs for proximity-based data exchange.
The Bump service provides four main endpoints:
- Health Check - Check service status and metrics
- Send Data - Send data for someone nearby to receive
- Receive Data - Receive data from someone nearby
- Bump - Unified endpoint to both send and receive data in a single request
All endpoints accept and return JSON data.
https://bump-production.up.railway.app
The health check API returns service status and statistics.
GET /
or
GET /bump/health
{
"status": "ok",
"version": "0.2.5",
"uptime_seconds": 3600,
"metrics": {
"queue_capacity": 1000,
"max_time_diff_ms": 2000,
"cleanup_interval_ms": 2500,
"max_distance_meters": 200
},
"queue_stats": {
"queue_size": 5,
"matches_count": 256,
"expired_count": 18,
"match_rate": 4.27,
"request_types": {
"send": 2,
"receive": 1,
"bump": 2
}
}
}| Field | Description |
|---|---|
status |
Service status ("ok", "degraded", or "error") |
version |
Current service version |
uptime_seconds |
How long the service has been running |
metrics |
Service configuration values |
queue_stats |
Statistics about the unified request queue |
└─ queue_size |
Total number of requests in queue |
└─ matches_count |
Total successful matches since startup |
└─ expired_count |
Total expired requests since startup |
└─ match_rate |
Average matches per second |
└─ request_types |
Breakdown of request types in queue |
The send API allows you to send data that can be received by another client nearby.
POST /bump/send
{
"matching_data": {
"timestamp": 1647529842000,
"location": {
"lat": 37.7749,
"long": -122.4194
},
"custom_key": "optional-secret-key"
},
"payload": "The data you want to transfer",
"ttl": 10000
}| Field | Description |
|---|---|
matching_data |
Parameters used to match with nearby receivers |
└─ timestamp |
Current time in milliseconds (use Date.now() in JavaScript) |
└─ location |
Geographic coordinates (optional but recommended) |
└─└─ lat |
Latitude between -90 and 90 |
└─└─ long |
Longitude between -180 and 180 |
└─ custom_key |
Secret key to ensure you match with the right person (optional) |
payload |
The data to send (string, can be text, URL, JSON string, etc.) |
ttl |
Time to live in milliseconds (how long to wait for a match) |
{
"status": "matched",
"sender_id": "send_request_123",
"receiver_id": "receive_request_456",
"timestamp": 1647529842123,
"payload": "The data you want to transfer"
}{
"status": "timeout",
"timestamp": 1647529852123,
"message": "No match found within 10000ms"
}| Field | Description |
|---|---|
status |
Result of the matching attempt ("matched" or "timeout") |
sender_id |
ID of the sender (your request) |
receiver_id |
ID of the receiver that matched |
timestamp |
When the match occurred |
payload |
The data that was transferred (in send responses) |
message |
Informational message (for timeouts) |
The receive API allows you to receive data from a nearby sender.
POST /bump/receive
{
"matching_data": {
"timestamp": 1647529842000,
"location": {
"lat": 37.7749,
"long": -122.4194
},
"custom_key": "optional-secret-key"
},
"ttl": 10000
}| Field | Description |
|---|---|
matchingData |
Parameters used to match with nearby senders |
└─ timestamp |
Current time in milliseconds (use Date.now() in JavaScript) |
└─ location |
Geographic coordinates (optional but recommended) |
└─└─ lat |
Latitude between -90 and 90 |
└─└─ long |
Longitude between -180 and 180 |
└─ custom_key |
Secret key to ensure you match with the right person (optional) |
ttl |
Time to live in milliseconds (how long to wait for a match) |
{
"status": "matched",
"sender_id": "send_request_123",
"receiver_id": "receive_request_456",
"timestamp": 1647529842123,
"payload": "The data that was sent to you"
}{
"status": "timeout",
"timestamp": 1647529852123,
"message": "No match found within 10000ms"
}| Field | Description |
|---|---|
status |
Result of the matching attempt ("matched" or "timeout") |
sender_id |
ID of the sender that matched |
receiver_id |
ID of the receiver (your request) |
timestamp |
When the match occurred |
payload |
The data that was sent to you |
message |
Informational message (for timeouts) |
Here's how to use the Bump service with JavaScript fetch API:
// Get current position
navigator.geolocation.getCurrentPosition(async (position) => {
// 1. Send data
const sendResponse = await fetch('https://bump-production.up.railway.app/bump/send', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
matching_data: {
timestamp: Date.now(),
location: {
lat: position.coords.latitude,
long: position.coords.longitude
},
custom_key: "my-secret-key-123"
},
payload: "Hello from sender!",
ttl: 10000 // Wait up to 10 seconds for a match
})
});
const sendResult = await sendResponse.json();
console.log("Send result:", sendResult);
// 2. Receive data
const receiveResponse = await fetch('https://bump-production.up.railway.app/bump/receive', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
matching_data: {
timestamp: Date.now(),
location: {
lat: position.coords.latitude,
long: position.coords.longitude
},
custom_key: "my-secret-key-123"
},
ttl: 10000 // Wait up to 10 seconds for a match
})
});
const receiveResult = await receiveResponse.json();
console.log("Receive result:", receiveResult);
});The Bump service uses a sophisticated matching algorithm with the following characteristics:
- Temporal Proximity: Matches requests that occur within a short time window (default: 500ms)
- Spatial Proximity: If location is provided, matches nearby requests (default: within 5 meters)
- Custom Keys: Optionally uses exact key matching for increased security
- Weighted Scoring: Uses a weighted scoring system to find the best match
- TTL-based Expiration: Requests expire after their TTL and can no longer be matched
- Use Accurate Timestamps: Always use the current time in milliseconds
- Provide Location: While optional, providing location improves matching accuracy
- Custom Keys: Use custom keys when you want to ensure you match with a specific user
- Appropriate TTL: Choose a TTL value that balances: - User patience (how long they're willing to wait) - Expected proximity (physically closer users match faster) - Network conditions (slower networks need longer TTLs)
- Handle Timeouts: Always implement timeout handling in your client
The /bump endpoint provides a unified way to both send and receive data in a single request.
POST /bump
{
"matching_data": {
"timestamp": 1714435201000,
"location": {
"lat": 37.7749,
"long": -122.4194
},
"custom_key": "optional-matching-key"
},
"payload": "Optional message or data to share",
"ttl": 500
}| Field | Type | Required | Description |
|---|---|---|---|
matching_data.timestamp |
number | Yes | Current time in milliseconds since epoch |
matching_data.location |
object | No | Geographic coordinates for proximity matching |
matching_data.location.lat |
number | - | Latitude in decimal degrees |
matching_data.location.long |
number | - | Longitude in decimal degrees |
matching_data.custom_key |
string | No | Optional identifier for exact matching |
payload |
any | No | Data to share with the matched request |
ttl |
number | No | Time to live in milliseconds (default: 500ms) |
{
"status": "matched",
"sender_id": "request-id-456",
"receiver_id": "request-id-123",
"timestamp": 1714435201500,
"payload": "Payload from the matching request",
"message": "Match successful"
}{
"status": "timeout",
"timestamp": 1714435210000,
"message": "No match found within specified TTL"
}| Field | Type | Description |
|---|---|---|
status |
string | Result of the request ("matched" or "timeout") |
sender_id |
string | ID of your request |
receiver_id |
string | ID of the matched request |
timestamp |
number | When the match occurred (milliseconds since epoch) |
payload |
any | Data received from the matched request |
message |
string | Optional informational message |
// Get current position
navigator.geolocation.getCurrentPosition(async (position) => {
const bumpResponse = await fetch('https://bump-production.up.railway.app/bump', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
matching_data: {
timestamp: Date.now(),
location: {
lat: position.coords.latitude,
long: position.coords.longitude
},
custom_key: "room-123"
},
payload: "Hello from client A!",
ttl: 1000 // Wait up to 1 second for a match
})
});
const result = await bumpResponse.json();
console.log("Bump result:", result);
if (result.status === "matched") {
console.log("Received payload:", result.payload);
}
});- Simplified Implementation: Use a single endpoint for both sending and receiving data
- Reduced Requests: Complete an exchange with just one request per client
- Symmetric Behavior: Both sides of a match are treated identically
- Flexible Data Exchange: Both parties can optionally send data in the same transaction
| Status Code | Description | Solution |
|---|---|---|
| 429 Too Many Requests | Queue is full | Try again later with exponential backoff |
| 408 Request Timeout | No match found within TTL | Increase TTL or try again |
| 400 Bad Request | Invalid request format | Check request format and parameters |
| 500 Internal Server Error | Server issue | Check the service status and try again later |