MyPlace API
Integrate guest data and receive real-time event notifications from your venues.
Base URL https://api.myplaceconnect.net
Authentication
All requests require an API key in the x-api-key header.
curl -H "x-api-key: YOUR_API_KEY" \
https://api.myplaceconnect.net/v1/guests
Create keys in Account > Developers > API Keys. Maximum 3 per venue.
Rate Limits
100 requests per hour per IP address. Returns 429 when exceeded.
Error Codes
| Status | Meaning |
|---|---|
200 | Success |
201 | Created |
400 | Bad Request — missing or invalid fields |
401 | Unauthorized — invalid or missing API key |
404 | Not Found |
429 | Too Many Requests |
500 | Internal Server Error |
Guest Object
| Field | Type | Description |
|---|---|---|
email | string | Primary identifier (unique per venue) |
firstName | string | Guest's first name |
lastName | string | Guest's last name |
phoneNumber | string | Phone number (E.164 format recommended) |
gender | string | M, F, or other |
country | string | ISO 3166-1 alpha-2 country code |
over18 | boolean | Age verification flag |
over21 | boolean | Age verification flag (US) |
tags | string[] | Custom labels (appended on update, not replaced) |
visitFrequency | integer | Number of visits to venue |
first_seen | string | First visit timestamp |
last_seen | string | Most recent visit timestamp |
language | string | Detected device language |
locations | object[] | Venues the guest has visited |
devices | string[] | MAC addresses of guest's devices |
subscribedTo | object[] | Integration subscription status (MailChimp, etc.) |
List Guests
/v1/guests| Parameter | Type | Default | Description |
|---|---|---|---|
page | integer | 1 | Page number |
per_page | integer | 10 | Results per page (max 1000) |
Response 200
{
"status": "OK",
"data": [
{
"email": "john@example.com",
"firstName": "John",
"lastName": "Doe",
"phoneNumber": "+353851234567",
"gender": "M",
"over18": true,
"tags": ["vip"],
"visitFrequency": 5
}
],
"metadata": {
"total_results": 150,
"page": 1,
"per_page": 10
}
}
Get Guest
/v1/guests/{email}Returns a single guest by email address.
Response 200
{
"status": "OK",
"data": {
"email": "john@example.com",
"firstName": "John",
"lastName": "Doe",
"phoneNumber": "+353851234567",
"gender": "M",
"country": "IE",
"over18": true,
"tags": ["vip", "regular"],
"visitFrequency": 5,
"first_seen": "15/01/2024, 10:30",
"last_seen": "27/04/2026, 14:15"
}
}
Create Guest
/v1/guests| Field | Type | Required |
|---|---|---|
email | string | Yes |
firstName | string | No |
lastName | string | No |
phoneNumber | string | No |
over18 | boolean | No |
gender | string | No |
country | string | No |
tags | string[] | No |
Request
{
"email": "john@example.com",
"firstName": "John",
"lastName": "Doe",
"phoneNumber": "+353851234567",
"over18": true,
"gender": "M",
"country": "IE",
"tags": ["imported"]
}
Response 201
{
"message": "Guest created successfully",
"guestId": "john@example.com",
"data": { ... }
}
Update Guest
/v1/guests/{email}Partial updates supported. Tags are appended, not replaced.
Request
{
"firstName": "Jonathan",
"tags": ["vip"]
}
Response 200
{
"message": "Guest updated successfully",
"guestId": "john@example.com",
"data": {
"email": "john@example.com",
"firstName": "Jonathan",
"lastName": "Doe",
"tags": ["regular", "vip"]
}
}
Delete Guest
/v1/guests/{email}Permanently removes a guest from your venue.
Response 200
{
"message": "Guest with id: john@example.com deleted",
"status": true
}
Unsubscribe Guest
/v1/guests/unsubscribe/{email}Removes marketing consent and triggers removal from connected integrations (MailChimp, Klaviyo, etc.).
Response 200
{
"message": "Guest john@example.com unsubscribed successfully",
"status": true
}
Webhooks
Webhooks send real-time HTTP POST notifications to your server when events occur in your venue. Instead of polling the API, your server gets notified automatically.
X-MyPlace-Signature, X-MyPlace-EventSetup
Go to Account > Developers > Webhooks and click Add Endpoint.
Enter your HTTPS URL, select events, and choose a venue.
After saving, a signing secret is displayed once. Copy it immediately.
Events
| Event | Trigger | Description |
|---|---|---|
user_added | New guest registers | Guest connects to WiFi and completes registration |
user_removed | Guest removed | Guest is deleted from your venue |
user_returned | Returning guest | Previously registered guest connects again |
Payloads
user_added / user_returned
{
"eventName": "User added",
"data": {
"firstName": "John",
"lastName": "Doe",
"email": "john@example.com",
"firstVisit": "2024-01-15",
"lastVisit": "2024-04-27",
"marketingAccepted": true,
"visitFrequency": 5,
"language": "en",
"gender": "M",
"over18": true,
"tags": ["vip", "regular"]
},
"created": 1714239450
}
user_removed
{
"eventName": "User removed",
"data": {
"userId": "john@example.com",
"deleted_at": 1714239450
},
"created": 1714239450
}
Verifying Signatures
Every webhook includes an X-MyPlace-Signature header — an HMAC-SHA256 hash of the request body signed with your webhook secret.
const crypto = require('crypto');
function verifyWebhook(req, secret) {
const signature = req.headers['x-myplace-signature'];
const body = JSON.stringify(req.body);
const expected = crypto
.createHmac('sha256', secret)
.update(body)
.digest('hex');
return signature === expected;
}
app.post('/webhook', express.json(), (req, res) => {
if (!verifyWebhook(req, process.env.MYPLACE_WEBHOOK_SECRET)) {
return res.status(401).json({ error: 'Invalid signature' });
}
const { eventName, data } = req.body;
console.log(`Received ${eventName}:`, data);
res.status(200).json({ received: true });
});
import hmac, hashlib
def verify_webhook(body, signature, secret):
expected = hmac.new(
secret.encode(), body.encode(), hashlib.sha256
).hexdigest()
return hmac.compare_digest(signature, expected)
@app.route('/webhook', methods=['POST'])
def handle_webhook():
sig = request.headers.get('X-MyPlace-Signature')
if not verify_webhook(request.get_data(as_text=True), sig, SECRET):
return jsonify({'error': 'Invalid signature'}), 401
event = request.json
return jsonify({'received': True})
$payload = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_MYPLACE_SIGNATURE'] ?? '';
$expected = hash_hmac('sha256', $payload, $secret);
if (!hash_equals($expected, $signature)) {
http_response_code(401);
exit('Invalid signature');
}
$event = json_decode($payload, true);
Testing
Click the Test button next to your webhook in the admin panel. A signed test payload is sent:
{
"eventName": "test",
"data": {
"message": "This is a test webhook from MyPlace",
"webhookId": "abc-123",
"timestamp": 1714239450000
},
"created": 1714239450
}
Test events appear in delivery logs and can be used to verify your endpoint and signature validation.
Best Practices
200 OK within 10 seconds. Process webhook data asynchronously.- Always use HTTPS endpoints
- Verify signatures to prevent spoofing
- Handle duplicates using the
createdtimestamp - Monitor delivery logs in the admin panel
- After regenerating your secret, update your server immediately
- Return
200for unknown event types — don't reject them