API & Webhook Integration
Last updated March 2026
Porter provides a REST API and webhook system so you can integrate visitor management into your existing tools and workflows. Use the API to query visitor data programmatically and webhooks to receive real-time event notifications.
Getting Your API Key
To use the Porter API, you first need to generate an API key from your dashboard.
- Navigate to Settings > API
- Click "Generate API Key"
- Copy the key immediately — it will only be shown once
- Store the key securely (e.g., in a secrets manager or environment variable)
You can revoke an API key at any time and generate a new one. Revoking a key immediately invalidates it — any integration using that key will stop working.
Authentication
All API requests must be authenticated using your API key and sent over HTTPS.
API Key Header
Include your API key in the X-API-Key header with every request:
X-API-Key: your_api_key_hereRate Limiting
- Rate limit: 100 requests per minute per API key
- Exceeding the limit returns a
429 Too Many Requestsresponse - The response includes a
Retry-Afterheader indicating when you can retry - All requests must use HTTPS — HTTP requests are rejected
Available Endpoints
The Porter API provides the following endpoints for interacting with your visitor management data.
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/v1/visitors | List all visitors with pagination and filters |
| GET | /api/v1/visitors/:id | Get a specific visitor record by ID |
| POST | /api/v1/visitors/pre-register | Pre-register a visitor |
| GET | /api/v1/locations | List all locations |
| GET | /api/v1/contractors | List all contractors |
Webhook Setup
Webhooks let Porter push real-time event notifications to your server. Instead of polling the API, you receive data the moment something happens.
Creating a Webhook
- Navigate to Settings > Webhooks
- Click "Add Webhook"
- Enter the URL where you want to receive webhook events
- Select the events you want to subscribe to
- Click "Save"
Available Events
visitor.checked_in— fired when a visitor checks invisitor.checked_out— fired when a visitor checks outvisitor.pre_registered— fired when a visitor is pre-registeredcontractor.approved— fired when a contractor is approvedevacuation.activated— fired when evacuation mode is activated
Testing Webhooks
After creating a webhook, click the "Test" button to send a sample payload to your URL. This lets you verify your endpoint is working correctly before relying on it in production.
Webhook Signatures
Every webhook request includes a signature so you can verify it genuinely came from Porter and hasn't been tampered with.
How Signatures Work
- Each webhook request includes an
X-Porter-Signatureheader - The signature is an HMAC-SHA256 hash of the request body
- The hash is computed using your webhook secret (found in Settings > Webhooks)
- Always verify signatures in production to prevent spoofed requests
Code Examples
Here are practical examples showing how to interact with the Porter API and verify webhook signatures.
cURL — List Visitors
curl -X GET https://yourapp.portervisitors.com/api/v1/visitors \
-H "X-API-Key: your_api_key_here" \
-H "Content-Type: application/json"JavaScript — List Visitors
const response = await fetch("https://yourapp.portervisitors.com/api/v1/visitors", {
method: "GET",
headers: {
"X-API-Key": "your_api_key_here",
"Content-Type": "application/json",
},
});
const data = await response.json();
console.log(data.visitors);Python — List Visitors
import requests
response = requests.get(
"https://yourapp.portervisitors.com/api/v1/visitors",
headers={
"X-API-Key": "your_api_key_here",
"Content-Type": "application/json",
},
)
data = response.json()
print(data["visitors"])JavaScript — Verify Webhook Signature
import crypto from "crypto";
function verifyWebhookSignature(body, signature, secret) {
const expected = crypto
.createHmac("sha256", secret)
.update(body)
.digest("hex");
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}
// In your webhook handler:
const isValid = verifyWebhookSignature(
rawBody,
req.headers["x-porter-signature"],
process.env.PORTER_WEBHOOK_SECRET
);
if (!isValid) {
return res.status(401).json({ error: "Invalid signature" });
}Python — Verify Webhook Signature
import hmac
import hashlib
def verify_webhook_signature(body: bytes, signature: str, secret: str) -> bool:
expected = hmac.new(
secret.encode(),
body,
hashlib.sha256
).hexdigest()
return hmac.compare_digest(signature, expected)
# In your webhook handler:
is_valid = verify_webhook_signature(
request.body,
request.headers.get("X-Porter-Signature"),
os.environ["PORTER_WEBHOOK_SECRET"],
)
if not is_valid:
return JsonResponse({"error": "Invalid signature"}, status=401)