Fork of tiredofit/docker-freescout with a custom API & Webhooks module that provides free REST API endpoints and outgoing webhook support — no paid module required.
- FreeScout Docker setup with MariaDB and automated backups
- CustomWebhooks module — free REST API endpoints compatible with FreeScout's official API format
- Outgoing webhook notifications on conversation events
- SMTP support via Mailpit for local development
git clone https://github.com/kzamanbd/docker-freescout.git
cd docker-freescout/examples
docker compose -f compose-no-proxy.yml up -dWait 2-5 minutes for the first boot to complete.
# Set API key in FreeScout .env
docker exec freescout-app bash -c "echo 'CUSTOM_API_KEY=your-api-key-here' >> /www/html/.env"
# Rebuild autoload, enable module, and clear cache
docker exec freescout-app bash -c "cd /www/html && composer dump-autoload && php artisan module:enable CustomWebhooks && php artisan freescout:clear-cache"Log in to FreeScout at http://localhost:8080 and go to Profile icon > Notifications, then enable notifications for new conversations and customer replies.
- URL: http://localhost:8080
- Email: admin@admin.com
- Password: freescout
All endpoints require the X-FreeScout-API-Key header.
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/conversations |
List conversations (supports mailboxId, customerId, status params) |
POST |
/api/conversations |
Create a new conversation |
GET |
/api/conversations/{id} |
Get conversation (supports ?embed=threads) |
POST |
/api/conversations/{id} |
Update conversation (status, assignee, subject) |
POST |
/api/conversations/{id}/threads |
Add a reply or note to a conversation |
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/customers |
List customers (supports email param) |
POST |
/api/customers |
Create a new customer |
POST |
/api/customers/{id} |
Update a customer |
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/mailboxes |
List all mailboxes |
Create a customer:
curl -X POST http://localhost:8080/api/customers \
-H "X-FreeScout-API-Key: your-api-key-here" \
-H "Content-Type: application/json" \
-d '{
"firstName": "John",
"lastName": "Doe",
"emails": [{"value": "john@example.com", "type": "work"}]
}'Create a conversation:
curl -X POST http://localhost:8080/api/conversations \
-H "X-FreeScout-API-Key: your-api-key-here" \
-H "Content-Type: application/json" \
-d '{
"type": "email",
"mailboxId": 1,
"subject": "Need help with my order",
"customer": {"id": 1},
"threads": [
{"type": "customer", "text": "Hello, I need help with my order."}
]
}'Add a reply:
curl -X POST http://localhost:8080/api/conversations/1/threads \
-H "X-FreeScout-API-Key: your-api-key-here" \
-H "Content-Type: application/json" \
-d '{
"type": "customer",
"text": "Any update on this?",
"customer": {"email": "john@example.com"}
}'When CUSTOM_WEBHOOK_URL is configured, the module sends POST requests for these events:
| Event | Trigger |
|---|---|
conversation.created_by_customer |
Customer creates a new conversation |
conversation.created_by_agent |
Agent creates a new conversation |
conversation.customer_replied |
Customer adds a reply |
conversation.agent_replied |
Agent adds a reply |
conversation.note_added |
Internal note added |
conversation.status_changed |
Conversation status changes |
conversation.assigned |
Conversation assignee changes |
Webhook payload format:
{
"event": "conversation.created_by_customer",
"timestamp": "2026-03-30T10:00:00+00:00",
"data": {
"conversation": {
"id": 1,
"number": 1,
"subject": "Need help",
"status": 1,
"mailbox_id": 1,
"customer_email": "john@example.com",
"created_at": "2026-03-30T10:00:00+00:00"
},
"thread": {
"id": 1,
"type": 1,
"body": "Hello, I need help.",
"created_at": "2026-03-30T10:00:00+00:00"
}
}
}If CUSTOM_WEBHOOK_SECRET is set, payloads include an X-Webhook-Signature header (HMAC-SHA256).
Add these to the FreeScout container .env file (/www/html/.env):
| Variable | Description | Required |
|---|---|---|
CUSTOM_API_KEY |
API key for authenticating incoming requests | Yes |
CUSTOM_WEBHOOK_URL |
URL to POST webhook events to | No |
CUSTOM_WEBHOOK_SECRET |
Secret for signing webhook payloads (HMAC-SHA256) | No |
examples/data/Modules/CustomWebhooks/
├── Config/config.php # Module configuration
├── Http/
│ ├── Controllers/ApiController.php # REST API endpoints
│ ├── Middleware/ApiAuth.php # API key authentication
│ └── routes.php # Route definitions
├── Listeners/WebhookListener.php # Outgoing webhook handler
├── Providers/CustomWebhooksServiceProvider.php # Service provider
└── module.json # Module metadata
This API is compatible with the official FreeScout API format. To connect an external application (e.g., a Laravel app):
FREESCOUT_URL=http://localhost:8080/api
FREESCOUT_MAILBOX_ID=1
FREESCOUT_API_KEY=your-api-key-hereThe API uses the same X-FreeScout-API-Key header and response format as the official paid module.
The compose file is preconfigured to send emails via Mailpit for local development:
- SMTP_HOST=host.docker.internal
- SMTP_PORT=1025
- SMTP_TLS=off
- SMTP_STARTTLS=offView captured emails at http://localhost:8025 (Mailpit UI).
For production, replace with your SMTP server:
- SMTP_HOST=smtp.example.com
- SMTP_PORT=587
- SMTP_TLS=on
- SMTP_STARTTLS=on| Parameter | Description | Default |
|---|---|---|
ADMIN_EMAIL |
Administrator email for login | |
ADMIN_PASS |
Administrator password | |
DB_HOST |
Database host | freescout-db |
DB_NAME |
Database name | freescout |
DB_USER |
Database username | freescout |
DB_PASS |
Database password | freescout |
SITE_URL |
Public URL of the site | |
SMTP_HOST |
SMTP server hostname | postfix-relay |
SMTP_PORT |
SMTP server port | 25 |
SMTP_TLS |
Enable TLS | off |
SMTP_STARTTLS |
Enable STARTTLS | off |
DISPLAY_ERRORS |
Show errors on site | FALSE |
TIMEZONE |
Container timezone | America/Vancouver |
| Directory | Description |
|---|---|
./data |
Persistent data (sessions, cache, modules) |
./logs |
Nginx and PHP logs |
./db |
MariaDB data files |
./dbbackup |
Automated database backups |
| Port | Description |
|---|---|
8080 |
FreeScout HTTP |
docker exec -it freescout-app bashdocker exec freescout-app bash -c "cd /www/html && php artisan freescout:clear-cache"docker exec freescout-app bash -c "cd /www/html && php artisan freescout:update-folder-counters"docker exec freescout-app bash -c "tail -50 /www/html/storage/logs/laravel-$(date +%Y-%m-%d).log"MIT. See LICENSE for more details.