accounts
Accounts API Documentation
Base URL
/api/sales/accounts
Authentication
All endpoints require JWT authentication. Include the JWT token in the Authorization header:
Authorization: Bearer <your-jwt-token>
Rate Limiting
All endpoints are limited to 10 requests per second.
Endpoints
1. Get All Accounts
Retrieve all accounts for the authenticated workspace with filters and pagination.
Endpoint: POST /api/sales/accounts/
Request (Full):
- Method: POST
- Headers: Authorization required
- Body:
{
"filters": {
"accounts": ["123e4567-e89b-12d3-a456-426614174000"],
"name": "search term",
"opportunities_state": ["openDeals", "wonDeals"],
"area_min": 100,
"area_max": 1000,
"page": "MTIz",
"page_size": 10
}
}
Request (Lite - for selects):
{
"action": "lite"
}
Request Fields (all optional):
action: Set to "lite" for minimal response (uuid and name only, no pagination)filters: Object containing filter criteriaaccounts: Array of account UUIDs to filter by (array of strings, UUID format)contacts: Array of contact UUIDs to filter accounts that have these contacts associated (array of strings, UUID format)name: Search term for account name (string, case-insensitive partial match)opportunities_state: Filter accounts by opportunity states (array of strings, enum: "openDeals", "wonDeals", "lostDeals")area_min: Minimum hectares (integer, only accounts with associated fields)area_max: Maximum hectares (integer, only accounts with associated fields)farms_uuid: Array of farm UUIDs to filter accounts by related farms through resources_enterprise (array of strings, UUID format)page: Pagination cursor from previous response (string)page_size: Number of accounts per page (integer, default: 10, max: 1000)
Response (Full):
{
"code": 0,
"data": [
{
"uuid": "123e4567-e89b-12d3-a456-426614174000",
"name": "Example Corp",
"active": true,
"country": 1,
"tax_id": "20-12345678-9",
"owner": {
"first_name": "John",
"last_name": "Smith"
},
"contacts": [
{
"uuid": "456e7890-e89b-12d3-a456-426614174001",
"first_name": "John",
"last_name": "Doe"
}
],
"more_contacts": 3,
"associated_fields": {
"quantity": 5,
"total_hectares": 1250.5
},
"opportunities": {
"openDeals": {
"purchase": 5,
"sale": 1,
"exchange": 0
},
"wonDeals": {
"purchase": 3,
"sale": 0,
"exchange": 2
},
"lostDeals": {
"purchase": 2,
"sale": 1,
"exchange": 0
}
}
}
],
"next_page": "MTIz"
}
Response (Lite):
{
"code": 0,
"data": [
{
"uuid": "123e4567-e89b-12d3-a456-426614174000",
"name": "Example Corp"
},
{
"uuid": "456e7890-e89b-12d3-a456-426614174001",
"name": "Another Company"
}
]
}
Response Fields (Full):
uuid: Unique identifier (string, UUID format)name: Company name (string)active: Active status (boolean, true if not inactivated)country: Country ID (integer)tax_id: Tax identification number (string)owner: Object with owner informationfirst_name: Owner first name (string)last_name: Owner last name (string)
contacts: Array with first associated contact (oldest by fecha_ini)uuid: Contact UUID (string)first_name: Contact first name (string)last_name: Contact last name (string)
more_contacts: Number of additional contacts associated to this account (integer)associated_fields: Object with associated fields informationquantity: Number of fields/lotes associated (integer)total_hectares: Total hectares from all associated fields (number)
opportunities: Object with opportunity counts by stateopenDeals: Object with open opportunity counts by typepurchase: Count of purchase opportunities (integer)sale: Count of sale opportunities (integer)exchange: Count of exchange opportunities (integer)
wonDeals: Object with won opportunity counts by typepurchase: Count of purchase opportunities (integer)sale: Count of sale opportunities (integer)exchange: Count of exchange opportunities (integer)
lostDeals: Object with lost opportunity counts by typepurchase: Count of purchase opportunities (integer)sale: Count of sale opportunities (integer)exchange: Count of exchange opportunities (integer)
next_page: Cursor for next page (string, nullable)
Response Fields (Lite):
uuid: Unique identifier (string, UUID format)name: Company name (string)
Filter Examples:
- Get all accounts (no filters):
{}
- Filter by specific account UUIDs:
{
"filters": {
"accounts": [
"123e4567-e89b-12d3-a456-426614174000",
"456e7890-e89b-12d3-a456-426614174001"
]
}
}
- Search by name:
{
"filters": {
"name": "Corp"
}
}
- Filter accounts with open deals:
{
"filters": {
"opportunities_state": ["openDeals"]
}
}
- Filter accounts with open or won deals:
{
"filters": {
"opportunities_state": ["openDeals", "wonDeals"]
}
}
- Combined filters with pagination:
{
"filters": {
"name": "Example",
"opportunities_state": ["wonDeals"],
"page_size": 20
}
}
- Filter by minimum hectares:
{
"filters": {
"area_min": 100
}
}
- Filter by maximum hectares:
{
"filters": {
"area_max": 5000
}
}
- Filter by hectares range:
{
"filters": {
"area_min": 100,
"area_max": 5000
}
}
- Filter by contacts:
{
"filters": {
"contacts": ["123e4567-e89b-12d3-a456-426614174000"]
}
}
- Filter by farms:
{
"filters": {
"farms_uuid": ["123e4567-e89b-12d3-a456-426614174000"]
}
}
- Lite mode for select dropdowns:
{
"action": "lite"
}
2. Get Account by UUID
Retrieve a specific account by its UUID.
Endpoint: GET /api/sales/accounts/account
Request:
- Query Parameters:
uuid: Account UUID (string, required, UUID format)
Response:
{
"code": 0,
"data": {
"uuid": "123e4567-e89b-12d3-a456-426614174000",
"country": 1,
"tax_id": "20-12345678-9",
"name": "Example Corp",
"address": "123 Main St",
"location": "Buenos Aires",
"draft": false,
"created_date": "2024-01-01T00:00:00",
"inactivation_date": null
}
}
Error Codes:
- Code 5: "Account not found" - The specified account UUID doesn't exist or doesn't belong to the workspace
3. Create Account
Create a new account.
Endpoint: POST /api/sales/accounts/account
Request:
{
"action": "create",
"country": 1,
"tax_id": "20-12345678-9",
"name": "Example Corp",
"address": "123 Main St",
"location": "Buenos Aires"
}
Request Fields:
action: Must be "create" (string, required)country: Country ID (integer, required, minimum 1)tax_id: Tax ID/CUIT (string, required, 1-20 characters)name: Company name (string, required, 1-255 characters)address: Address (string, optional, max 255 characters)location: Location (string, optional, max 255 characters)
Response:
{
"code": 0,
"message": "Account created successfully",
"uuid": "123e4567-e89b-12d3-a456-426614174000",
"data": {
"country": 1,
"tax_id": "20-12345678-9",
"name": "Example Corp",
"address": "123 Main St",
"location": "Buenos Aires",
"draft": false
}
}
Error Codes:
- Code 6: "Account already exists in this workspace" - An account with the same country and tax_id already exists
4. Update Account
Update an existing account.
Endpoint: POST /api/sales/accounts/account
Request:
{
"action": "update",
"uuid": "123e4567-e89b-12d3-a456-426614174000",
"country": 1,
"tax_id": "20-12345678-9",
"name": "Updated Corp Name",
"address": "456 New St",
"location": "Córdoba"
}
Request Fields:
action: Must be "update" (string, required)uuid: Account UUID (string, required, UUID format)country: Country ID (integer, required, minimum 1)tax_id: Tax ID/CUIT (string, required, 1-20 characters)name: Company name (string, required, 1-255 characters)address: Address (string, optional, max 255 characters)location: Location (string, optional, max 255 characters)
Response:
{
"code": 0,
"message": "Account updated successfully",
"uuid": "123e4567-e89b-12d3-a456-426614174000",
"data": {
"country": 1,
"tax_id": "20-12345678-9",
"name": "Updated Corp Name",
"address": "456 New St",
"location": "Córdoba"
}
}
Error Codes:
- Code 5: "Account not found" - The specified account UUID doesn't exist or doesn't belong to the workspace
- Code 6: "Account already exists in this workspace" - Another account with the same country and tax_id already exists
5. Delete Account
Delete an existing account (soft delete).
Endpoint: POST /api/sales/accounts/account
Request:
{
"action": "delete",
"uuid": "123e4567-e89b-12d3-a456-426614174000"
}
Request Fields:
action: Must be "delete" (string, required)uuid: Account UUID (string, required, UUID format)
Response:
{
"code": 0,
"message": "Account deleted successfully",
"uuid": "123e4567-e89b-12d3-a456-426614174000"
}
Error Codes:
- Code 5: "Account not found" - The specified account UUID doesn't exist or doesn't belong to the workspace
6. Inactivate Account
Inactivate an account. Only the owner can inactivate their accounts.
Endpoint: POST /api/sales/accounts/account
Request:
{
"action": "inactivate",
"uuid": "123e4567-e89b-12d3-a456-426614174000"
}
Request Fields:
action: Must be "inactivate" (string, required)uuid: Account UUID (string, required, UUID format)
Response:
{
"code": 0,
"message": "Account inactivated successfully",
"uuid": "123e4567-e89b-12d3-a456-426614174000"
}
Notes:
- Only the owner (creator) of the account can inactivate it
- Sets
fecha_inactivacionto current timestamp - Returns error if account is already inactive
Error Codes:
- Code 5: "Account not found" - The specified account UUID doesn't exist or doesn't belong to the workspace, or account already inactive
- Code 8: "Cannot inactivate account with open opportunities" - The account has open opportunities and cannot be inactivated
- Code 9: "You can only inactivate accounts you own" - User is not the owner of the account
7. Activate Account
Activate an inactive account. Only the owner can activate their accounts.
Endpoint: POST /api/sales/accounts/account
Request:
{
"action": "activate",
"uuid": "123e4567-e89b-12d3-a456-426614174000"
}
Request Fields:
action: Must be "activate" (string, required)uuid: Account UUID (string, required, UUID format)
Response:
{
"code": 0,
"message": "Account activated successfully",
"uuid": "123e4567-e89b-12d3-a456-426614174000"
}
Notes:
- Only the owner (creator) of the account can activate it
- Sets
fecha_inactivacionto NULL - Returns error if account is already active
Error Codes:
- Code 5: "Account not found or already active" - Cannot activate (not found or already active)
8. Validate Tax ID
Validate a tax ID format and check if an account with that tax ID already exists in the workspace.
Endpoint: POST /api/sales/accounts/account
Request:
{
"action": "validate_tax_id",
"tax_id": "20123456789"
}
Request Fields:
action: Must be "validate_tax_id" (string, required)tax_id: Tax ID to validate (string, required, 1-20 characters)
Response (Valid and Not Exists):
{
"code": 0,
"data": {
"valid": true,
"exists": false
}
}
Response (Valid and Exists):
{
"code": 0,
"data": {
"valid": true,
"exists": true,
"uuid": "123e4567-e89b-12d3-a456-426614174000",
"name": "Existing Company Name",
"country": 1
}
}
Response Fields:
valid: Whether the tax_id format is valid (boolean)exists: Whether an account with this tax_id already exists (boolean)uuid: UUID of existing account (string, only if exists=true)name: Name of existing account (string, only if exists=true)country: Country ID of existing account (integer, only if exists=true)
Notes:
- Validates tax_id format using a flexible regex pattern (alphanumeric with optional hyphens, dots, slashes)
- Checks for existing accounts in the same workspace with the same tax_id
- Accepts various international tax ID formats (CUIT, CNPJ, RUT, NIT, RFC, EIN, CIF, etc.)
Error Codes:
- Code 7: "Invalid tax_id format" - The tax_id doesn't match the expected format
Error Response Format
All error responses follow this format:
{
"res": "error",
"code": <error_code>,
"info": "<error_description>"
}
HTTP Status Codes:
- 200: Success
- 400: Bad Request (validation errors)
- 401: Unauthorized (missing or invalid JWT token)
- 429: Too Many Requests (rate limit exceeded)
- 500: Internal Server Error
Business Rules
Uniqueness Constraint
- Each account must have a unique combination of
country+tax_idwithin the same workspace - When creating or updating, the system validates this constraint
- If violated, error code 2 is returned
Soft Delete
- Accounts are not physically deleted from the database
- Instead, the
fecha_finfield is set to the current timestamp - Deleted accounts won't appear in list or get operations
Field Mapping
The API uses English field names in requests/responses, but the database uses Spanish names:
| API Field | Database Field | Description |
|---|---|---|
country | pais | Country ID |
tax_id | cuit | Tax ID/CUIT |
name | nombre | Company name |
address | direccion | Address |
location | localizacion | Location |
draft | borrador | Draft status |
created_date | fecha_ini | Creation date |
inactivation_date | fecha_inactivacion | Inactivation date |
Usage Examples
JavaScript/Fetch Example:
// Get all accounts
const response = await fetch('/api/sales/accounts/', {
method: 'POST',
headers: {
'Authorization': 'Bearer ' + token,
'Content-Type': 'application/json'
},
body: JSON.stringify({})
});
// Get accounts with filters
const filteredResponse = await fetch('/api/sales/accounts/', {
method: 'POST',
headers: {
'Authorization': 'Bearer ' + token,
'Content-Type': 'application/json'
},
body: JSON.stringify({
filters: {
name: 'Example',
opportunities_state: 'openDeals',
page_size: 20
}
})
});
// Create account
const createResponse = await fetch('/api/sales/accounts/account', {
method: 'POST',
headers: {
'Authorization': 'Bearer ' + token,
'Content-Type': 'application/json'
},
body: JSON.stringify({
action: 'create',
country: 1,
tax_id: '20-12345678-9',
name: 'My Company',
address: '123 Business St',
location: 'Buenos Aires'
})
});
// Update account
const updateResponse = await fetch('/api/sales/accounts/account', {
method: 'POST',
headers: {
'Authorization': 'Bearer ' + token,
'Content-Type': 'application/json'
},
body: JSON.stringify({
action: 'update',
uuid: '123e4567-e89b-12d3-a456-426614174000',
country: 1,
tax_id: '20-12345678-9',
name: 'Updated Company Name',
address: '456 New Address',
location: 'Córdoba'
})
});
Country Codes
The country field expects an integer ID. Common values:
1: Argentina- (Other country codes should be obtained from the countries reference API)