Create a new client
curl --request POST \
--url https://app.thareja.ai/api/v1/client/create \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "Acme Corporation",
"email": "contact@acmecorp.com",
"phone": "+1-555-123-4567",
"company": "Acme Corporation Inc.",
"website": "https://www.acmecorp.com",
"billing_address1": "123 Main Street",
"billing_address2": "Suite 100",
"city": "San Francisco",
"state": "California",
"zipcode": "94102",
"country": "United States",
"notes": "<string>",
"net_term": 30,
"tax_id": "12-3456789",
"tax_rate": 8.5
}
'import requests
url = "https://app.thareja.ai/api/v1/client/create"
payload = {
"name": "Acme Corporation",
"email": "contact@acmecorp.com",
"phone": "+1-555-123-4567",
"company": "Acme Corporation Inc.",
"website": "https://www.acmecorp.com",
"billing_address1": "123 Main Street",
"billing_address2": "Suite 100",
"city": "San Francisco",
"state": "California",
"zipcode": "94102",
"country": "United States",
"notes": "<string>",
"net_term": 30,
"tax_id": "12-3456789",
"tax_rate": 8.5
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: 'Acme Corporation',
email: 'contact@acmecorp.com',
phone: '+1-555-123-4567',
company: 'Acme Corporation Inc.',
website: 'https://www.acmecorp.com',
billing_address1: '123 Main Street',
billing_address2: 'Suite 100',
city: 'San Francisco',
state: 'California',
zipcode: '94102',
country: 'United States',
notes: '<string>',
net_term: 30,
tax_id: '12-3456789',
tax_rate: 8.5
})
};
fetch('https://app.thareja.ai/api/v1/client/create', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://app.thareja.ai/api/v1/client/create",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'name' => 'Acme Corporation',
'email' => 'contact@acmecorp.com',
'phone' => '+1-555-123-4567',
'company' => 'Acme Corporation Inc.',
'website' => 'https://www.acmecorp.com',
'billing_address1' => '123 Main Street',
'billing_address2' => 'Suite 100',
'city' => 'San Francisco',
'state' => 'California',
'zipcode' => '94102',
'country' => 'United States',
'notes' => '<string>',
'net_term' => 30,
'tax_id' => '12-3456789',
'tax_rate' => 8.5
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://app.thareja.ai/api/v1/client/create"
payload := strings.NewReader("{\n \"name\": \"Acme Corporation\",\n \"email\": \"contact@acmecorp.com\",\n \"phone\": \"+1-555-123-4567\",\n \"company\": \"Acme Corporation Inc.\",\n \"website\": \"https://www.acmecorp.com\",\n \"billing_address1\": \"123 Main Street\",\n \"billing_address2\": \"Suite 100\",\n \"city\": \"San Francisco\",\n \"state\": \"California\",\n \"zipcode\": \"94102\",\n \"country\": \"United States\",\n \"notes\": \"<string>\",\n \"net_term\": 30,\n \"tax_id\": \"12-3456789\",\n \"tax_rate\": 8.5\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://app.thareja.ai/api/v1/client/create")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"Acme Corporation\",\n \"email\": \"contact@acmecorp.com\",\n \"phone\": \"+1-555-123-4567\",\n \"company\": \"Acme Corporation Inc.\",\n \"website\": \"https://www.acmecorp.com\",\n \"billing_address1\": \"123 Main Street\",\n \"billing_address2\": \"Suite 100\",\n \"city\": \"San Francisco\",\n \"state\": \"California\",\n \"zipcode\": \"94102\",\n \"country\": \"United States\",\n \"notes\": \"<string>\",\n \"net_term\": 30,\n \"tax_id\": \"12-3456789\",\n \"tax_rate\": 8.5\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.thareja.ai/api/v1/client/create")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"Acme Corporation\",\n \"email\": \"contact@acmecorp.com\",\n \"phone\": \"+1-555-123-4567\",\n \"company\": \"Acme Corporation Inc.\",\n \"website\": \"https://www.acmecorp.com\",\n \"billing_address1\": \"123 Main Street\",\n \"billing_address2\": \"Suite 100\",\n \"city\": \"San Francisco\",\n \"state\": \"California\",\n \"zipcode\": \"94102\",\n \"country\": \"United States\",\n \"notes\": \"<string>\",\n \"net_term\": 30,\n \"tax_id\": \"12-3456789\",\n \"tax_rate\": 8.5\n}"
response = http.request(request)
puts response.read_body{
"error": 400,
"message": "The email has already been taken."
}
{
"error": 400,
"message": "The email must be a valid email address."
}
{
"error": 400,
"message": "The email field is required."
}
{
"error": "This file can't be upload on server"
}
{
"error": 401,
"message": "Invalid or missing authentication token"
}
Client
Create Client
Create a new client with billing configuration, budget settings, and contact information
POST
/
api
/
v1
/
client
/
create
Create a new client
curl --request POST \
--url https://app.thareja.ai/api/v1/client/create \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "Acme Corporation",
"email": "contact@acmecorp.com",
"phone": "+1-555-123-4567",
"company": "Acme Corporation Inc.",
"website": "https://www.acmecorp.com",
"billing_address1": "123 Main Street",
"billing_address2": "Suite 100",
"city": "San Francisco",
"state": "California",
"zipcode": "94102",
"country": "United States",
"notes": "<string>",
"net_term": 30,
"tax_id": "12-3456789",
"tax_rate": 8.5
}
'import requests
url = "https://app.thareja.ai/api/v1/client/create"
payload = {
"name": "Acme Corporation",
"email": "contact@acmecorp.com",
"phone": "+1-555-123-4567",
"company": "Acme Corporation Inc.",
"website": "https://www.acmecorp.com",
"billing_address1": "123 Main Street",
"billing_address2": "Suite 100",
"city": "San Francisco",
"state": "California",
"zipcode": "94102",
"country": "United States",
"notes": "<string>",
"net_term": 30,
"tax_id": "12-3456789",
"tax_rate": 8.5
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: 'Acme Corporation',
email: 'contact@acmecorp.com',
phone: '+1-555-123-4567',
company: 'Acme Corporation Inc.',
website: 'https://www.acmecorp.com',
billing_address1: '123 Main Street',
billing_address2: 'Suite 100',
city: 'San Francisco',
state: 'California',
zipcode: '94102',
country: 'United States',
notes: '<string>',
net_term: 30,
tax_id: '12-3456789',
tax_rate: 8.5
})
};
fetch('https://app.thareja.ai/api/v1/client/create', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://app.thareja.ai/api/v1/client/create",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'name' => 'Acme Corporation',
'email' => 'contact@acmecorp.com',
'phone' => '+1-555-123-4567',
'company' => 'Acme Corporation Inc.',
'website' => 'https://www.acmecorp.com',
'billing_address1' => '123 Main Street',
'billing_address2' => 'Suite 100',
'city' => 'San Francisco',
'state' => 'California',
'zipcode' => '94102',
'country' => 'United States',
'notes' => '<string>',
'net_term' => 30,
'tax_id' => '12-3456789',
'tax_rate' => 8.5
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://app.thareja.ai/api/v1/client/create"
payload := strings.NewReader("{\n \"name\": \"Acme Corporation\",\n \"email\": \"contact@acmecorp.com\",\n \"phone\": \"+1-555-123-4567\",\n \"company\": \"Acme Corporation Inc.\",\n \"website\": \"https://www.acmecorp.com\",\n \"billing_address1\": \"123 Main Street\",\n \"billing_address2\": \"Suite 100\",\n \"city\": \"San Francisco\",\n \"state\": \"California\",\n \"zipcode\": \"94102\",\n \"country\": \"United States\",\n \"notes\": \"<string>\",\n \"net_term\": 30,\n \"tax_id\": \"12-3456789\",\n \"tax_rate\": 8.5\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://app.thareja.ai/api/v1/client/create")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"Acme Corporation\",\n \"email\": \"contact@acmecorp.com\",\n \"phone\": \"+1-555-123-4567\",\n \"company\": \"Acme Corporation Inc.\",\n \"website\": \"https://www.acmecorp.com\",\n \"billing_address1\": \"123 Main Street\",\n \"billing_address2\": \"Suite 100\",\n \"city\": \"San Francisco\",\n \"state\": \"California\",\n \"zipcode\": \"94102\",\n \"country\": \"United States\",\n \"notes\": \"<string>\",\n \"net_term\": 30,\n \"tax_id\": \"12-3456789\",\n \"tax_rate\": 8.5\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.thareja.ai/api/v1/client/create")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"Acme Corporation\",\n \"email\": \"contact@acmecorp.com\",\n \"phone\": \"+1-555-123-4567\",\n \"company\": \"Acme Corporation Inc.\",\n \"website\": \"https://www.acmecorp.com\",\n \"billing_address1\": \"123 Main Street\",\n \"billing_address2\": \"Suite 100\",\n \"city\": \"San Francisco\",\n \"state\": \"California\",\n \"zipcode\": \"94102\",\n \"country\": \"United States\",\n \"notes\": \"<string>\",\n \"net_term\": 30,\n \"tax_id\": \"12-3456789\",\n \"tax_rate\": 8.5\n}"
response = http.request(request)
puts response.read_body{
"error": 400,
"message": "The email has already been taken."
}
{
"error": 400,
"message": "The email must be a valid email address."
}
{
"error": 400,
"message": "The email field is required."
}
{
"error": "This file can't be upload on server"
}
{
"error": 401,
"message": "Invalid or missing authentication token"
}
Overview
Create a new client in your workspace. Clients can be associated with projects for billing and invoicing purposes. Each client includes billing configuration, budget settings, and contact information.Request Body
string
required
The name of the client or company.Example:
"Acme Corporation"string
required
The client’s email address. Must be unique across all clients.Format: Valid email addressExample:
"contact@acmecorp.com"file
Client profile picture or logo.Allowed formats: PNG, JPG, JPEGMax size: As per server configuration
string
Client’s phone number.Example:
"+1-555-123-4567"string
Company name (if different from client name).Example:
"Acme Corporation Inc."string
Client’s website URL.Example:
"https://www.acmecorp.com"Billing Address
string
Primary billing address line.Example:
"123 Main Street"string
Secondary billing address line (suite, apartment, etc.).Example:
"Suite 100"string
City for billing address.Example:
"San Francisco"string
State or province for billing address.Example:
"California"string
ZIP or postal code for billing address.Example:
"94102"string
Country for billing address.Example:
"United States"Invoice Settings
string
Custom invoice notes for this client (if not using org_notes).Example:
"Payment due within 30 days of invoice date."integer
Custom net payment terms in days (if not using org_net_term).Example:
30string
Client’s tax identification number.Example:
"12-3456789"number
Tax rate percentage for invoices.Example:
8.5Budget Settings
string
Type of budget tracking.Allowed values:
"total_cost", "hours_cost"Example: "total_cost"number
Budget amount in currency.Example:
50000.00number
Budget amount in hours (for hours_cost type).Example:
500integer
Percentage at which to notify about budget usage.Example:
80Response
object
The created client object.
Show properties
Show properties
integer
Unique identifier for the client.
string
Client name.
string
Client email address.
string
URL to client profile picture/logo.
string
Client phone number.
string
Company name.
string
Client website URL.
integer
Team ID this client belongs to.
integer
User ID who created the client.
object
Invoice configuration settings.
object
Budget configuration settings.
string
Timestamp when client was created.
string
Timestamp when client was last updated.
Example Request
curl --request POST \
--url https://staging.thareja.org/api/v3/client/create \
--header 'Authorization: Bearer YOUR_API_TOKEN' \
--header 'Content-Type: application/json' \
--data '{
"name": "Acme Corporation",
"email": "contact@acmecorp.com",
"phone": "+1-555-123-4567",
"company": "Acme Corporation Inc.",
"website": "https://www.acmecorp.com",
"billing_address1": "123 Main Street",
"billing_address2": "Suite 100",
"city": "San Francisco",
"state": "California",
"zipcode": "94102",
"country": "United States",
"org_notes": true,
"org_net_term": true,
"tax_id": "12-3456789",
"tax_rate": 8.5,
"budget_type": "total_cost",
"budget_cost": 50000.00,
"budget_notify_at": 80
}'
Example Request (JavaScript)
fetch('https://staging.thareja.org/api/v3/client/create', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: "Acme Corporation",
email: "contact@acmecorp.com",
phone: "+1-555-123-4567",
company: "Acme Corporation Inc.",
website: "https://www.acmecorp.com",
billing_address1: "123 Main Street",
billing_address2: "Suite 100",
city: "San Francisco",
state: "California",
zipcode: "94102",
country: "United States",
org_notes: true,
org_net_term: true,
tax_id: "12-3456789",
tax_rate: 8.5,
budget_type: "total_cost",
budget_cost: 50000.00,
budget_notify_at: 80
})
})
.then(response => response.json())
.then(data => console.log(data));
Example Request - With Profile Picture
curl --request POST \
--url https://staging.thareja.org/api/v3/client/create \
--header 'Authorization: Bearer YOUR_API_TOKEN' \
--form 'name="Acme Corporation"' \
--form 'email="contact@acmecorp.com"' \
--form 'phone="+1-555-123-4567"' \
--form 'profile=@/path/to/logo.png' \
--form 'org_notes=true' \
--form 'org_net_term=true'
Example Request (JavaScript with File Upload)
const formData = new FormData();
formData.append('name', 'Acme Corporation');
formData.append('email', 'contact@acmecorp.com');
formData.append('phone', '+1-555-123-4567');
formData.append('profile', fileInput.files[0]);
formData.append('org_notes', 'true');
formData.append('org_net_term', 'true');
fetch('https://staging.thareja.org/api/v3/client/create', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_TOKEN'
},
body: formData
})
.then(response => response.json())
.then(data => console.log(data));
Example Response
{
"success": {
"id": 10,
"name": "Acme Corporation",
"email": "contact@acmecorp.com",
"profile": "https://s3.amazonaws.com/bucket/profiles/client-logo.png",
"phone": "+1-555-123-4567",
"company": "Acme Corporation Inc.",
"website": "https://www.acmecorp.com",
"team_id": 1,
"user_id": 1,
"invoices": {
"tax_id": "12-3456789",
"late_fee": "no",
"lineItem": "project-date",
"net_term": 30,
"tax_rate": 8.5,
"frequency": "weekly",
"delay_days": 5,
"fixedPrice": 0,
"autoInvoice": "off",
"lineItemText": "By user Project and Date",
"amountBasedOn": "hourly",
"reminder_days": "10",
"include_expense": "no",
"include_non_billable_time": "no"
},
"budget": {
"budgetType": "total_cost",
"rate": "bill",
"cost": 50000.00,
"hours": 0,
"notifyAt": 80,
"reset": "never",
"startDate": null,
"include_non_billable_time": true
},
"isInternalClient": false,
"created_at": "2025-11-28T10:30:00Z",
"updated_at": "2025-11-28T10:30:00Z"
}
}
Error Responses
{
"error": 400,
"message": "The email has already been taken."
}
{
"error": 400,
"message": "The email must be a valid email address."
}
{
"error": 400,
"message": "The email field is required."
}
{
"error": "This file can't be upload on server"
}
{
"error": 401,
"message": "Invalid or missing authentication token"
}
Default Invoice Settings
When a client is created, the following default invoice settings are applied:| Setting | Default Value | Description |
|---|---|---|
late_fee | no | Late fee charges disabled |
lineItem | project-date | Invoice line items by project and date |
net_term | 30 | 30-day payment terms (or org default) |
tax_rate | 0 | No tax rate (unless specified) |
frequency | weekly | Weekly invoice generation |
delay_days | 5 | 5-day delay before auto-invoice |
autoInvoice | off | Auto-invoicing disabled |
amountBasedOn | hourly | Hourly-based billing |
reminder_days | 10 | Payment reminder 10 days after |
include_expense | no | Expenses not included |
include_non_billable_time | no | Non-billable time excluded |
Default Budget Settings
| Setting | Default Value | Description |
|---|---|---|
budgetType | total_cost | Track by total cost |
rate | bill | Use billable rate |
cost | 0 | No budget limit |
hours | 0 | No hour limit |
notifyAt | 80 | Notify at 80% usage |
reset | never | Budget never resets |
include_non_billable_time | true | Include non-billable |
Organization Settings Inheritance
Using org_notes
- When
true: Client inherits organization’s default invoice notes - When
false: Custom notes can be specified
Using org_net_term
- When
true: Client inherits organization’s default payment terms - When
false: Custom net terms can be specified
File Upload
Profile Picture
- Allowed formats: PNG, JPG, JPEG only
- Storage: Uploaded to Amazon S3
- Path:
profiles/directory - URL: Full S3 URL returned in response
- Security: Only image files allowed, other formats rejected
Address Handling
Billing address is automatically copied to mailing address:billing_address1→mailing_address1billing_address2→mailing_address2city→mailing_citystate→mailing_statezipcode→mailing_zip
Webhook Integration
After successful client creation, a Zapier webhook is triggered:{
"event": "new_client",
"payload": {
"id": 10,
"name": "Acme Corporation",
"profile": "https://s3.url/logo.png",
"retrieved_at": "2025-11-28 10:30:00"
},
"criteria": {
"team_id": 1
}
}
Name Sanitization
Client names are automatically sanitized by removing:- Single quotes (
') - Double quotes (
") - Commas (
,) - Semicolons (
;) - Angle brackets (
<,>) - Square brackets (
[,]) - Exclamation marks (
!) - Plus signs (
+) - Pipe symbols (
|)
Notes
- Email uniqueness: Client email must be unique across the entire system
- Team assignment: Client is automatically assigned to your current team
- User tracking: Your user ID is recorded as the creator
- Profile storage: Profile pictures are stored on S3 and returned as full URLs
- Address duplication: Billing address is copied to mailing address
- Budget tracking: Budget settings can be configured per client
- Invoice automation: Various invoice settings can be customized
- Webhook triggers: Zapier webhooks fire on successful creation
- Character filtering: Client names are sanitized for database safety
Best Practices
- Always provide complete billing address for invoicing
- Use organization defaults (
org_notes,org_net_term) for consistency - Set appropriate budget limits and notification thresholds
- Upload high-quality logos for professional invoices
- Verify email uniqueness before submission
- Configure tax rates according to client location
- Set realistic payment terms based on client relationship
Related Endpoints
- Get Clients - List all clients
- Get Client - Retrieve client details
- Update Client - Update client information
- Delete Client - Remove a client
- Get Client Invoices - View client invoices
Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Body
application/jsonmultipart/form-data
Example:
"Acme Corporation"
Example:
"contact@acmecorp.com"
Example:
"+1-555-123-4567"
Example:
"Acme Corporation Inc."
Example:
"https://www.acmecorp.com"
Example:
"123 Main Street"
Example:
"Suite 100"
Example:
"San Francisco"
Example:
"California"
Example:
"94102"
Example:
"United States"
Example:
30
Example:
"12-3456789"
Example:
8.5