Create Customer
Create a new customer.
Endpoint
POST /api/customers
Request
POST https://app.getmanageit.io/api/customers
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json
Request Body
The request should be sent as multipart/form-data with the following structure:
email: [email protected]
name: Test
last_name: Test
phone: "654645654654"
"custom_fields[2][key]": new 2
"custom_fields[2][cust]": new 1
"business_information[company_name]": "111"
"custom_fields[2][file_upload][formats][]": jpg
"permissions[invoice][view-invoice]": "1"
"permissions[contract][view-contract]": "1"
"permissions[invoice][create-invoice]": "1"
profile_photo_path: string
"custom_fields[2][file_upload][files][]": string
Sample JSON Payload
While the API uses multipart/form-data, here's what the equivalent JSON structure would look like for reference:
Basic Customer Creation
{
"email": "[email protected]",
"name": "John",
"last_name": "Doe",
"phone": "555-123-4567",
"business_information": {
"company_name": "Acme Corp"
},
"permissions": {
"invoice": {
"view-invoice": "1",
"create-invoice": "1"
},
"contract": {
"view-contract": "1"
}
}
}
Customer with Custom Fields
{
"email": "[email protected]",
"name": "Jane",
"last_name": "Smith",
"phone": "555-987-6543",
"business_information": {
"company_name": "Tech Solutions Inc"
},
"permissions": {
"invoice": {
"view-invoice": "1",
"create-invoice": "1",
"edit-invoice": "1"
},
"contract": {
"view-contract": "1",
"create-contract": "1"
},
"proposal": {
"view-proposal": "1"
}
},
"custom_fields": {
"52": {
"key": "search_test",
"value": "Engineering Department"
},
"68": {
"key": "birthday",
"value": "January"
},
"54": {
"key": "q",
"value": "Important client notes"
}
}
}
Customer with File Upload Fields
{
"email": "[email protected]",
"name": "Mike",
"last_name": "Wilson",
"phone": "555-456-7890",
"business_information": {
"company_name": "Design Studio"
},
"permissions": {
"invoice": {
"view-invoice": "1",
"create-invoice": "1"
},
"contract": {
"view-contract": "1"
}
},
"custom_fields": {
"55": {
"key": "jpg",
"file_upload": {
"formats": ["DOCX", "DOC"],
"files": ["contract.pdf", "proposal.docx"]
}
}
}
}
Note: These JSON examples are for reference only. The actual API requires multipart/form-data format.
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
email | string | Yes | Customer's email address |
name | string | Yes | Customer's first name |
last_name | string | Yes | Customer's last name |
phone | string | Yes | Customer's phone number |
business_information[company_name] | string | Yes | Company name |
profile_photo_path | string(binary) | Yes | Profile photo file |
custom_fields[N][key] | string | No | Custom field key (N = field ID) |
custom_fields[N][value] | string | No | Custom field value |
custom_fields[N][file_upload][formats][] | string | No | Allowed file formats for file fields |
custom_fields[N][file_upload][files][] | string(binary) | No | File upload for file fields |
permissions[module][permission] | string | Yes | Module-specific permissions |
Permissions System
The permissions system controls what modules and actions a customer can access. All permissions are required and must be set to "1" to grant access.
Permission Structure
permissions[MODULE][ACTION] = "1"
Available Modules and Actions
| Module | Available Actions | Description |
|---|---|---|
invoice | view-invoice, create-invoice, edit-invoice, delete-invoice | Invoice management permissions |
contract | view-contract, create-contract, edit-contract, delete-contract | Contract management permissions |
proposal | view-proposal, create-proposal, edit-proposal, delete-proposal | Proposal management permissions |
meeting | view-meeting, create-meeting, edit-meeting, delete-meeting | Meeting management permissions |
Required Permissions Example
# Minimum required permissions for basic access
-F "permissions[invoice][view-invoice]=1"
-F "permissions[contract][view-contract]=1"
-F "permissions[invoice][create-invoice]=1"
Full Permissions Example
# Grant all permissions
-F "permissions[invoice][view-invoice]=1"
-F "permissions[invoice][create-invoice]=1"
-F "permissions[invoice][edit-invoice]=1"
-F "permissions[invoice][delete-invoice]=1"
-F "permissions[contract][view-contract]=1"
-F "permissions[contract][create-contract]=1"
-F "permissions[contract][edit-contract]=1"
-F "permissions[contract][delete-contract]=1"
-F "permissions[proposal][view-proposal]=1"
-F "permissions[proposal][create-proposal]=1"
-F "permissions[proposal][edit-proposal]=1"
-F "permissions[proposal][delete-proposal]=1"
-F "permissions[meeting][view-meeting]=1"
-F "permissions[meeting][create-meeting]=1"
-F "permissions[meeting][edit-meeting]=1"
-F "permissions[meeting][delete-meeting]=1"
Custom Fields System
Custom fields are dynamically configured by each user and vary significantly between accounts. The field structure depends on how the user has set up their custom fields in their account settings.
Custom Field Structure
custom_fields[FIELD_ID][PROPERTY] = VALUE
Field Types and Their Properties
| Field Type | Type ID | Properties | Example |
|---|---|---|---|
| Text Field | 1 | key, value | custom_fields[52][key]=departmentcustom_fields[52][value]=Engineering |
| Select Dropdown | 5 | key, value | custom_fields[68][key]=birthdaycustom_fields[68][value]=January |
| Text Area | 7 | key, value | custom_fields[54][key]=notescustom_fields[54][value]=Important client |
| File Upload | 9 | key, file_upload[formats][], file_upload[files][] | custom_fields[55][key]=documentscustom_fields[55][file_upload][formats][]=pdfcustom_fields[55][file_upload][files][][email protected] |
How to Determine Field Configuration
You must first query the user's custom field configuration to know which fields are available:
- Get Custom Fields Configuration (separate endpoint)
- Identify Field IDs and Types from the configuration
- Use the correct structure based on field type
Custom Field Examples by Type
Text Field (Type 1)
# Single line text input
-F "custom_fields[52][key]=department"
-F "custom_fields[52][value]=Engineering"
Select Dropdown (Type 5)
# Dropdown with predefined options
-F "custom_fields[68][key]=priority"
-F "custom_fields[68][value]=high"
Text Area (Type 7)
# Multi-line text input
-F "custom_fields[54][key]=notes"
-F "custom_fields[54][value]=This is a longer description or notes about the customer"
File Upload (Type 9)
# File upload with format restrictions
-F "custom_fields[55][key]=documents"
-F "custom_fields[55][file_upload][formats][]=pdf"
-F "custom_fields[55][file_upload][formats][]=docx"
-F "custom_fields[55][file_upload][files][][email protected]"
-F "custom_fields[55][file_upload][files][][email protected]"
Important Notes About Custom Fields
- Field IDs are unique per user account - The same field might have different IDs for different users
- Field types determine the structure - Each type requires different properties
- File upload fields have restrictions - Check the
fileConfigin the field configuration - Some fields may be required - Check the field configuration for required status
- Values must match field options - For select fields, values must be from the predefined options
Getting Custom Field Configuration
Before creating a customer, you should fetch the available custom fields:
# Get custom fields configuration (example endpoint)
GET /api/custom-fields
This will return the field structure like:
{
"data": [
{
"id": 52,
"type": 1,
"name": "Department",
"key": "department",
"required": true,
"fields": {
"options": null
}
},
{
"id": 55,
"type": 9,
"name": "Documents",
"key": "documents",
"required": false,
"fields": {
"fileConfig": {
"acceptFile": ["PDF", "DOCX"],
"allowMultiple": true,
"maxFiles": 5
}
}
}
]
}
Response
{
"data": {
"id": 310,
"name": "simitri",
"last_name": "dimitri",
"phone": "555-987-6543",
"profile_photo_path": null,
"email": "[email protected]",
"stripe_customer_flag": false,
"business_information": {
"company_name": "Tech Solutions Inc",
"company_phone": "5627143119",
"company_email": null,
"company_website": null,
"address_1": null,
"address_2": null,
"country": null,
"city": null,
"state": null,
"zip_code": null,
"fax": null
},
"custom_fields": [
{
"id": 54,
"user_id": 231,
"location": 3,
"type": 7,
"name": "q",
"key": "q",
"description": null,
"placeholder": null,
"fields": {
"options": ["234"],
"fileConfig": null
},
"group": "c5cd8947-93a8-4f22-bfed-d7dc45657afb",
"created_at": "2025-07-29T12:32:45.000000Z",
"updated_at": "2025-07-29T12:32:45.000000Z",
"custom_field_values": [
{
"id": 136,
"owner_id": 231,
"user_id": 310,
"custom_field_id": 54,
"value": "234",
"created_at": "2025-10-01T00:40:54.000000Z",
"updated_at": "2025-10-01T00:40:54.000000Z"
}
]
}
],
"notes": [],
"activity_log": [],
"permissions": {
"4": "view-invoice",
"8": "view-contract",
"12": "view-proposal"
}
}
}
Response Fields
| Field | Type | Description |
|---|---|---|
data | object | The created customer data |
data.id | integer | Unique identifier for the customer |
data.name | string | Customer's first name |
data.last_name | string | Customer's last name |
data.phone | string | Customer's phone number |
data.profile_photo_path | string/null | URL to customer's profile photo |
data.email | string | Customer's email address |
data.stripe_customer_flag | boolean | Whether customer has Stripe integration |
data.business_information | object | Customer's business details |
data.custom_fields | array | Array of custom fields for the customer |
data.notes | array | Array of notes for the customer (empty on creation) |
data.activity_log | array | Array of activity log entries (empty on creation) |
data.permissions | object | Customer's permissions for different modules |
Business Information Fields
| Field | Type | Description |
|---|---|---|
company_name | string/null | Company name |
company_phone | string/null | Company phone number |
company_email | string/null | Company email address |
company_website | string/null | Company website URL |
address_1 | string/null | Primary address line |
address_2 | string/null | Secondary address line |
country | string/null | Country |
city | string/null | City |
state | string/null | State/Province |
zip_code | string/null | Postal/ZIP code |
fax | string/null | Fax number |
Custom Fields Structure
| Field | Type | Description |
|---|---|---|
id | integer | Unique identifier for the custom field |
user_id | integer | ID of the user who created the field |
location | integer | Field location identifier |
type | integer | Field type (1=text, 5=select, 7=text, 9=file) |
name | string | Display name of the field |
key | string | Unique key for the field |
description | string/null | Field description |
placeholder | string/null | Placeholder text |
fields | object | Field configuration options |
group | string | Field group identifier |
created_at | datetime | When the field was created |
updated_at | datetime | When the field was last updated |
custom_field_values | array | Array of values for this customer |
Custom Field Values Structure
| Field | Type | Description |
|---|---|---|
id | integer | Unique identifier for the field value |
owner_id | integer | ID of the field owner |
user_id | integer | ID of the customer |
custom_field_id | integer | ID of the custom field |
value | mixed | The field value (string, array, etc.) |
created_at | datetime | When the value was created |
updated_at | datetime | When the value was last updated |
Permissions Structure
The permissions object contains key-value pairs where:
- Key: Permission ID (integer as string)
- Value: Permission name (string)
Common permissions include:
"4": "view-invoice""8": "view-contract""12": "view-proposal""16": "view-meeting"
Status Codes
| Code | Description |
|---|---|
| 201 | Created |
| 400 | Bad Request |
| 401 | Unauthorized |
| 422 | Validation Error |
| 500 | Server Error |