API Documentation

Developer reference for the EventStuffer REST API

Overview

The EventStuffer API provides programmatic access to the platform's booking, staff, payment, and messaging features. The API follows REST conventions, returns JSON responses, and uses standard HTTP status codes.

Base URLhttps://eventstuffer.com/api
API Versionv1
Content Typeapplication/json
Rate Limit1,000 requests/hour per API key

Authentication

The API supports two authentication methods:

API Key (Enterprise)

Enterprise subscribers and administrators can generate API keys from the dashboard. Include the key in the Authorization header:

Authorization: Bearer ps_a1b2c3d4e5f6...

API keys are prefixed with ps_ and are 68 characters long. They are hashed with SHA-256 on our servers and never stored in plaintext. You can create up to 5 active keys per account.

Session Cookie (Web UI)

For browser-based integrations, you can use session cookie authentication. After logging in through /auth/login, the session cookie (connect.sid) authenticates subsequent requests. CSRF protection requires including the X-CSRF-Token header (from the csrf-token meta tag) on all mutating requests.

API Key Management
MethodEndpointDescription
POST/api/keysCreate a new API key (session auth required)
GET/api/keysList your API keys (masked)
DELETE/api/keys/:idRevoke an API key

Staff Profiles

Search, browse, and retrieve staff member profiles.

GET /api/v1/companions

Search for available staff members with filters.

ParameterTypeDescription
locationstringFilter by city or country name (partial match)
servicestringFilter by service type (e.g., "DJ", "Bartender", "Hostess")
min_pricenumberMinimum hourly rate
max_pricenumberMaximum hourly rate
datestringDate in YYYY-MM-DD format to check availability
pageintegerPage number (default: 1)
limitintegerResults per page (1-50, default: 12)

Example response:

{
  "companions": [
    {
      "id": 42,
      "first_name": "Maria",
      "profile_photo": "/uploads/photos/42/profile.jpg",
      "tagline": "Professional event hostess with 5 years experience",
      "hourly_rate": 45.00,
      "daily_rate": 300.00,
      "location_city": "Berlin",
      "location_country": "Germany",
      "service_types": "Event Hostess,Trade Show Hostess",
      "rating_avg": 4.8,
      "total_reviews": 23,
      "tier": "gold",
      "badges": ["verified", "top-rated"]
    }
  ],
  "page": 1,
  "limit": 12
}
GET /api/v1/companions/:id

Get detailed profile information for a specific staff member, including their latest reviews and portfolio items.

Response includes: full profile data, up to 10 most recent reviews, and approved portfolio items.

GET /api/v1/companions/:id/availability

Check a staff member's availability for a date range.

ParameterTypeRequiredDescription
start_datestringYesYYYY-MM-DD start of range
end_datestringYesYYYY-MM-DD end of range

Bookings

Create and track bookings through the API. Requires an API key with the book permission.

POST /api/v1/bookings

Create a new booking request. The booking will be created with a pending status, awaiting staff acceptance.

FieldTypeRequiredDescription
companion_idintegerYesStaff member ID
event_datestringYesEvent date (YYYY-MM-DD)
start_timestringYesStart time (HH:MM, 24-hour)
duration_hoursintegerYesDuration in hours (1-24)
service_typestringYesService type requested
locationstringYesEvent location/address
customer_emailstringYesEmail of the registered customer

Example request:

POST /api/v1/bookings
Content-Type: application/json
Authorization: Bearer ps_a1b2c3d4...

{
  "companion_id": 42,
  "event_date": "2026-05-15",
  "start_time": "18:00",
  "duration_hours": 4,
  "service_type": "Event Hostess",
  "location": "Messe Berlin, Messedamm 22, 14055 Berlin",
  "customer_email": "client@example.com"
}

Example response (201 Created):

{
  "success": true,
  "booking": {
    "id": 1234,
    "booking_code": "PS-A1B2C3D4",
    "total_amount": 180.00,
    "status": "pending"
  }
}
GET /api/v1/bookings/:code

Get the current status of a booking by its booking code.

Booking statuses:

  • pending — Awaiting staff acceptance
  • accepted — Staff has accepted, awaiting payment
  • paid — Payment received and held in escrow
  • completed — Event completed, payout initiated
  • cancelled — Cancelled by either party
  • disputed — Under dispute review

Payment Flow (Stripe Escrow)

All payments are processed through Stripe using an escrow model. The flow is as follows:

  1. Booking created — Client selects staff and creates a booking request via the platform or API.
  2. Staff accepts — The staff member reviews and accepts the booking. A payment intent is created.
  3. Client pays — Client completes payment via Stripe Checkout. Funds are held in escrow (not transferred to staff yet).
  4. Event occurs — Staff checks in at the event using the safety system and provides services.
  5. Completion confirmed — Client confirms completion (or it auto-completes 72 hours after the event end time).
  6. Payout initiated — Platform fee is deducted, and the remaining amount is transferred to the staff member's Stripe Connect account within 48 hours.

Payment details are never exposed through the API. All card data is handled exclusively by Stripe and never touches our servers. Payment intents use idempotency keys to prevent duplicate charges.

Cancellation Refunds
TimingRefund Amount
48+ hours before event100%
24-48 hours before event50%
<24 hours before event0% (or 50% with cancellation insurance)
Staff cancellation100% + priority rebooking

Real-Time Messaging (Socket.io)

Messaging between clients and staff is handled through Socket.io for real-time delivery. The messaging system supports:

  • Direct messages between booking parties
  • Group chat for multi-staff events
  • Typing indicators and online presence
  • Content filtering for inappropriate messages
  • Rate limiting: 100 events per socket per 60-second window
Socket Connection

After authenticating via session cookie, connect to the Socket.io namespace:

const socket = io('https://eventstuffer.com', {
  withCredentials: true
});

// Listen for new messages
socket.on('new_message', (data) => {
  console.log(data.sender_name, data.content);
});

// Send a message
socket.emit('send_message', {
  conversation_id: 123,
  content: 'Hello, I have a question about the event.'
});

The REST API also provides message history endpoints for server-side integrations:

MethodEndpointDescription
GET/messagesList conversations (session auth)
GET/messages/conversation/:idGet messages in a conversation
POST/messages/send/:userIdSend a message (max 5,000 characters)

Reviews and Ratings

Both clients and staff can leave reviews after a completed booking. Reviews include an overall star rating (1-5) and optional sub-ratings for specific aspects of the service.

MethodEndpointDescription
POST/reviews/booking/:bookingIdSubmit a review (session auth)
GET/reviews/user/:userIdGet reviews for a user
POST/reviews/:reviewId/respondRespond to a review (staff only)

Review submission fields:

  • rating (integer, 1-5) — Overall rating (required)
  • comment (string, max 2000 chars) — Written review text
  • punctuality, professionalism, communication, appearance (integer, 1-5) — Optional sub-ratings

Webhooks

Register HTTPS endpoints to receive real-time event notifications. Webhook payloads are signed with HMAC-SHA256 so you can verify authenticity.

Webhook Management
MethodEndpointDescription
POST/api/webhooksRegister a webhook endpoint (max 10 per user)
GET/api/webhooksList your webhook endpoints
DELETE/api/webhooks/:idDelete a webhook endpoint
POST/api/webhooks/:id/testSend a test event to an endpoint
Supported Events
EventDescription
booking.createdA new booking request has been created
booking.completedA booking has been marked as completed
booking.cancelledA booking has been cancelled by either party
payment.completedA payment has been successfully processed
review.createdA new review has been submitted
Signature Verification

Each webhook delivery includes an X-Webhook-Signature header containing an HMAC-SHA256 signature computed from the raw JSON payload body using your webhook secret. Verify like this:

const crypto = require('crypto');

function verifyWebhookSignature(payload, signature, secret) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(payload)
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected)
  );
}

Webhooks have 3 automatic retry attempts with exponential backoff (1s, 4s, 16s). After 10 consecutive failures, the endpoint is auto-disabled.

Rate Limiting

The API enforces rate limits to ensure platform stability:

ScopeLimitWindow
API key (general)1,000 requests1 hour
Webhook management30 requests15 minutes
Booking creation10 requests1 hour
Contact form5 submissions1 hour

Rate limit headers are included in all API responses:

  • X-RateLimit-Limit — Maximum requests allowed in the window
  • X-RateLimit-Remaining — Remaining requests in the current window
  • X-RateLimit-Reset — Unix timestamp when the window resets

When the limit is exceeded, the API returns 429 Too Many Requests.

Error Responses

All error responses follow a consistent JSON format:

{
  "error": "Human-readable error description"
}

For validation errors (from input validation), the response includes field-level detail:

{
  "errors": [
    {
      "field": "event_date",
      "message": "Invalid event date"
    },
    {
      "field": "companion_id",
      "message": "Invalid companion"
    }
  ]
}
HTTP Status Codes
CodeMeaning
200Success
201Resource created successfully
400Bad request (validation error, missing required fields)
401Authentication required (invalid or missing API key)
403Forbidden (insufficient permissions or subscription tier)
404Resource not found
422Validation errors (field-level details provided)
429Rate limit exceeded
500Internal server error

API Key Permissions

API keys are created with specific permission scopes. Currently supported permissions:

PermissionGrants Access To
readSearch companions, view profiles, check availability, view booking status
bookCreate bookings via the API

Enterprise subscription is required for API access. Administrators always have full API access regardless of subscription.