Appearance
API Documentation
This guide covers the REST API endpoints, authentication, request/response formats, and how to integrate with the Growstack CRM API.
Table of Contents
- Overview
- Authentication
- API Endpoints
- Request/Response Formats
- Error Handling
- Rate Limiting
- Webhooks
- Best Practices
Overview
What is the API?
The Growstack CRM API provides programmatic access to your application's data and functionality. It allows external applications and services to interact with your CRM, support, and business modules.
API Base URL
Base URL:
https://yourdomain.com/apiVersion:
- Current version: v1
- No version prefix required
Features
- ✅ RESTful API design
- ✅ JSON responses
- ✅ Authentication via Sanctum
- ✅ Rate limiting
- ✅ Webhook support
- ✅ Public and authenticated endpoints
Authentication
Sanctum Authentication
The API uses Laravel Sanctum for authentication. You need to obtain a token to access protected endpoints.
Getting an API Token
Step 1: Create API Token
Endpoint: POST /api/tokens
Request:
json
{
"email": "user@example.com",
"password": "password",
"device_name": "My App"
}Response:
json
{
"token": "1|abcdef1234567890..."
}Step 2: Use Token
Include in Headers:
Authorization: Bearer {token}Example:
Authorization: Bearer 1|abcdef1234567890...Token Management
Creating Tokens
Via Admin Panel:
- Go to Users → Edit User
- Go to API Tokens section
- Create new token
- Copy token immediately (shown once)
Revoking Tokens
Via Admin Panel:
- Go to Users → Edit User
- Go to API Tokens section
- Click Revoke on token
- Token immediately invalidated
API Endpoints
Public Endpoints
Public endpoints don't require authentication.
Services
List Services:
GET /api/public/servicesGet Service:
GET /api/public/services/{id}Events
List Events:
GET /api/public/eventsGet Upcoming Events:
GET /api/public/events/upcomingGet Event:
GET /api/public/events/{id}Get Event Tickets:
GET /api/public/events/{id}/ticketsCauses
List Causes:
GET /api/public/causesGet Featured Causes:
GET /api/public/causes/featuredGet Cause Categories:
GET /api/public/causes/categoriesGet Cause:
GET /api/public/causes/{id}Authenticated Endpoints
These endpoints require authentication.
Quotes
List Quotes:
GET /api/quotes
Authorization: Bearer {token}Create Quote:
POST /api/quotes
Authorization: Bearer {token}
Content-Type: application/json
{
"client_name": "Company Name",
"email": "client@example.com",
"fields": {
"service_type": "Web Development",
"budget": "5000"
}
}Get Quote:
GET /api/quotes/{id}
Authorization: Bearer {token}Get Quote Fields:
GET /api/quotes/fields/list
Authorization: Bearer {token}Services
List Services:
GET /api/services
Authorization: Bearer {token}Get Service:
GET /api/services/{id}
Authorization: Bearer {token}Create Booking:
POST /api/services/bookings
Authorization: Bearer {token}
Content-Type: application/json
{
"service_id": 1,
"date": "2024-12-25",
"time": "10:00",
"name": "John Doe",
"email": "john@example.com",
"phone": "+1234567890"
}Create Inquiry:
POST /api/services/inquiries
Authorization: Bearer {token}
Content-Type: application/json
{
"service_id": 1,
"name": "Jane Doe",
"email": "jane@example.com",
"message": "I'm interested in this service"
}List Bookings:
GET /api/services/bookings/list
Authorization: Bearer {token}List Inquiries:
GET /api/services/inquiries/list
Authorization: Bearer {token}Events
List Events:
GET /api/events
Authorization: Bearer {token}Get Upcoming Events:
GET /api/events/upcoming
Authorization: Bearer {token}Get Event:
GET /api/events/{id}
Authorization: Bearer {token}Get Event Tickets:
GET /api/events/{id}/tickets
Authorization: Bearer {token}Create Registration:
POST /api/events/registrations
Authorization: Bearer {token}
Content-Type: application/json
{
"event_id": 1,
"ticket_id": 1,
"quantity": 2,
"name": "John Doe",
"email": "john@example.com"
}List Registrations:
GET /api/events/registrations/list
Authorization: Bearer {token}Causes
Get Featured Causes:
GET /api/causes/featured
Authorization: Bearer {token}Get Cause Categories:
GET /api/causes/categories
Authorization: Bearer {token}Get Cause:
GET /api/causes/{id}
Authorization: Bearer {token}Create Donation:
POST /api/causes/donations
Authorization: Bearer {token}
Content-Type: application/json
{
"cause_id": 1,
"amount": 50.00,
"name": "John Doe",
"email": "john@example.com"
}List Donations:
GET /api/causes/donations/list
Authorization: Bearer {token}Media
List Media:
GET /api/media-picker
Authorization: Bearer {token}Upload Media:
POST /api/media-picker/upload
Authorization: Bearer {token}
Content-Type: multipart/form-data
file: [file]Payments
Stripe Payment Intent:
POST /api/payments/stripe/create-intent
Content-Type: application/json
{
"amount": 100.00,
"currency": "usd"
}PayPal Create Order:
POST /api/payments/paypal/create-order
Content-Type: application/json
{
"amount": 100.00,
"currency": "USD"
}Request/Response Formats
Request Format
Headers
Required:
Content-Type: application/json
Authorization: Bearer {token} (for authenticated endpoints)Optional:
Accept: application/jsonRequest Body
JSON Format:
json
{
"field1": "value1",
"field2": "value2"
}Response Format
Success Response
Structure:
json
{
"data": {
"id": 1,
"name": "Example",
"created_at": "2024-01-01T00:00:00.000000Z"
}
}List Response:
json
{
"data": [
{
"id": 1,
"name": "Example 1"
},
{
"id": 2,
"name": "Example 2"
}
],
"meta": {
"current_page": 1,
"per_page": 15,
"total": 2
}
}Error Response
Structure:
json
{
"message": "Error message",
"errors": {
"field": ["Error message"]
}
}Error Handling
HTTP Status Codes
Success Codes
- 200 OK: Request successful
- 201 Created: Resource created
- 204 No Content: Success, no content
Client Error Codes
- 400 Bad Request: Invalid request
- 401 Unauthorized: Authentication required
- 403 Forbidden: Permission denied
- 404 Not Found: Resource not found
- 422 Unprocessable Entity: Validation error
Server Error Codes
- 500 Internal Server Error: Server error
- 503 Service Unavailable: Service unavailable
Error Response Format
Example:
json
{
"message": "The given data was invalid.",
"errors": {
"email": [
"The email field is required.",
"The email must be a valid email address."
],
"name": [
"The name field is required."
]
}
}Handling Errors
Best Practices:
- Check status code
- Parse error response
- Display user-friendly messages
- Log errors for debugging
- Handle network errors
Rate Limiting
Rate Limits
Default Limits:
- Authenticated: 60 requests per minute
- Public: 30 requests per minute
Rate Limit Headers
Response Headers:
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 59
X-RateLimit-Reset: 1640995200Handling Rate Limits
Rate Limit Exceeded:
json
{
"message": "Too Many Attempts."
}Status Code: 429 Too Many Requests
Best Practices:
- Monitor rate limit headers
- Implement exponential backoff
- Cache responses when possible
- Batch requests when appropriate
Webhooks
Supported Webhooks
Payment Webhooks
Stripe:
POST /api/webhooks/stripePayPal:
POST /api/webhooks/paypalSquare:
POST /api/webhooks/squareKlarna:
POST /api/webhooks/klarnaAdyen:
POST /api/webhooks/adyenWebhook Configuration
Setting Up Webhooks
Get Webhook URL:
- Your webhook URL:
https://yourdomain.com/api/webhooks/{service}
- Your webhook URL:
Configure in Service:
- Go to service dashboard
- Add webhook URL
- Select events
Verify:
- Test webhook
- Verify received
- Check logs
Best Practices
API Usage
Use HTTPS:
- Always use HTTPS
- Protect tokens
- Secure data transmission
Store Tokens Securely:
- Don't expose in code
- Use environment variables
- Rotate regularly
Handle Errors Gracefully:
- Check status codes
- Parse error messages
- Provide user feedback
Respect Rate Limits:
- Monitor limits
- Implement backoff
- Cache when possible
Use Appropriate Endpoints:
- Use public endpoints when possible
- Authenticate only when needed
- Minimize requests
Security
Protect Tokens:
- Never commit to version control
- Use secure storage
- Rotate regularly
Validate Input:
- Validate all input
- Sanitize data
- Check types
Monitor Usage:
- Monitor API usage
- Check for abuse
- Review logs
CRM API
The CRM API provides programmatic access to contacts, accounts, leads, deals, activities, and pipelines. Requires the CRM module to be enabled.
Authentication
All CRM endpoints (except public lead capture) require a Sanctum bearer token:
Authorization: Bearer {token}CRM Endpoints (Authenticated)
Base path: /api/crm
| Method | Endpoint | Description |
|---|---|---|
| GET | /contacts | List contacts (paginated) |
| POST | /contacts | Create contact |
| GET | /contacts/{id} | Get contact |
| PUT/PATCH | /contacts/{id} | Update contact |
| DELETE | /contacts/{id} | Delete contact |
| GET | /accounts | List accounts |
| POST | /accounts | Create account |
| GET | /accounts/{id} | Get account |
| PUT/PATCH | /accounts/{id} | Update account |
| DELETE | /accounts/{id} | Delete account |
| GET | /leads | List leads |
| POST | /leads | Create lead |
| GET | /leads/{id} | Get lead |
| PUT/PATCH | /leads/{id} | Update lead |
| DELETE | /leads/{id} | Delete lead |
| POST | /leads/{id}/convert | Convert lead to contact/deal |
| GET | /deals | List deals |
| POST | /deals | Create deal |
| GET | /deals/{id} | Get deal |
| PUT/PATCH | /deals/{id} | Update deal |
| DELETE | /deals/{id} | Delete deal |
| POST | /deals/{id}/move-stage | Move deal to pipeline stage |
| GET | /activities | List activities |
| POST | /activities | Log activity |
| PUT/PATCH | /activities/{id} | Update activity |
| DELETE | /activities/{id} | Delete activity |
| GET | /pipelines | List pipelines with stages |
Query parameters: per_page, search, status, owner_id, pipeline_id, etc.
Activity filters: activityable_type (contact|account|lead|deal), activityable_id, owner_id
Public Lead Capture
Endpoint: POST /api/public/leads
Auth: None (rate limited: 10 requests/minute)
Module: CRM must be enabled
Request:
json
{
"first_name": "Jane",
"last_name": "Doe",
"email": "jane@example.com",
"phone": "+1234567890",
"company_name": "Acme Inc",
"description": "Interested in your services",
"source": "website-form"
}Alternatively use "name": "Jane Doe" instead of first/last name.
Response (201):
json
{
"success": true,
"message": "Lead captured successfully.",
"data": {
"id": 42,
"email": "jane@example.com",
"status": "new"
}
}Inbound Webhook (Zapier / Make)
Endpoint: POST /api/public/webhooks/leads
Auth: Optional X-Webhook-Secret header (set CRM_WEBHOOK_SECRET in .env)
Rate limit: 30 requests/minute
Same request body as public lead capture.
Outbound Webhooks
When CRM_WEBHOOK_URL is configured, the system POSTs JSON to that URL on:
deal.won— when a deal moves to a won stagelead.created— when a lead is captured via public API/webhook
Environment variables:
CRM_WEBHOOK_URL=https://hooks.zapier.com/hooks/catch/...
CRM_WEBHOOK_SECRET=your-secret-keyCSV Import / Export (Admin)
Available at CRM → Import / Export in the admin panel (/admin/crm/import-export).
| Action | Route |
|---|---|
| Export contacts | GET /admin/crm/export/contacts |
| Export leads | GET /admin/crm/export/leads |
| Export deals | GET /admin/crm/export/deals |
| Import contacts | POST /admin/crm/import/contacts (CSV file) |
| Import leads | POST /admin/crm/import/leads (CSV file) |