Saltar al contenido principal

opportunities

Ver en Git


Opportunities API Documentation

Base URL

/api/sales/opportunities

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 Opportunity by UUID

Retrieve a specific opportunity by its UUID with full details.

Endpoint: GET /api/sales/opportunities/

Request:

  • Query Parameters:
    • uuid: Opportunity UUID (string, required, UUID format)

Response:

{
"uuid": "123e4567-e89b-12d3-a456-426614174000",
"name": "Sale Opportunity",
"uuid_account": "456e7890-e89b-12d3-a456-426614174001",
"account_name": "Example Corp",
"owner_id": 123,
"owner_name": "John",
"owner_lastname": "Doe",
"id_opportunity_type": 1,
"id_opportunity_state": 1,
"uuid_stage": "789e0123-e89b-12d3-a456-426614174002",
"order": 1.5,
"tags": [1, 2, 3],
"start_date": "2024-01-15T10:30:00",
"updated_at": "2024-01-20T15:45:00",
"deleted_at": null,
"comment": "Important client",
"id_loss_reason": null,
"loss_reason_description": null,
"fields": [
{
"uuid_field": "abc12345-e89b-12d3-a456-426614174003",
"nombre": "Field 1",
"farm_name": "Farm A"
}
],
"notes": [],
"attachments": [],
"contacts": [
{
"uuid": "def67890-e89b-12d3-a456-426614174004",
"first_name": "Jane",
"last_name": "Smith",
"phone": "+1234567890",
"email": "jane@example.com"
}
],
"operations": []
}

Error Codes:

  • Code 2: "UUID required" - Missing uuid parameter
  • Code 7: "Opportunity not found" - The specified opportunity UUID doesn't exist

2. List Opportunities

List opportunities with filters and pagination. Supports three view modes: Kanban (all stages), Single Column (one stage), or Flat List (no stage grouping).

Endpoint: POST /api/sales/opportunities/

Request (Kanban View - All Stages):

{
"action": "get",
"limit": 15,
"uuid_accounts": ["123e4567-e89b-12d3-a456-426614174000"],
"owner_ids": [123, 456],
"id_opportunity_types": [1, 2],
"id_opportunity_states": [1],
"start_date": "2024-01-01",
"end_date": "2024-12-31"
}

Request (Single Column View):

{
"action": "get",
"uuid_stage": "789e0123-e89b-12d3-a456-426614174002",
"page": "MTIz",
"limit": 15
}

Request (Flat List View):

{
"action": "get",
"no_stages": true,
"page": "MTIz",
"limit": 15
}

Request Fields:

  • action: Must be "get" (string, required)
  • page: Pagination cursor (string, optional, base64 encoded)
  • limit: Number of results per page (integer, default: 15)
  • uuid_accounts: Filter by account UUIDs (array of strings, optional)
  • uuid_contacts: Filter by contact UUIDs (array of strings, optional)
  • owner_ids: Filter by owner user IDs (array of integers, optional)
  • id_opportunity_types: Filter by opportunity types (array of integers, optional)
  • id_opportunity_states: Filter by states (array of integers, optional)
  • uuid_stage: Filter by specific stage UUID (string, optional, use "null" or "0" for opportunities without stage)
  • start_date: Filter by start date (string, optional, ISO format)
  • end_date: Filter by end date (string, optional, ISO format)
  • no_stages: Flat list without stage grouping (boolean, default: false)

Response (Kanban View):

{
"stages": [
{
"uuid_stage": "789e0123-e89b-12d3-a456-426614174002",
"name": "Prospecting",
"order": 1,
"opportunity_count": 25,
"opportunities": [...],
"next_page": "MTIz"
}
]
}

Response (Single Column / Flat List):

{
"data": [...],
"next_page": "MTIz"
}

Error Codes:

  • Code 1: "JSON required" - Missing request body
  • Code 3: "Action required" - Missing action field

3. Create Opportunity

Create a new opportunity.

Endpoint: POST /api/sales/opportunities/

Request:

{
"action": "create",
"name": "New Sale Opportunity",
"uuid_account": "456e7890-e89b-12d3-a456-426614174001",
"id_opportunity_type": 1,
"uuid_stage": "789e0123-e89b-12d3-a456-426614174002",
"tags": [1, 2],
"comment": "High priority",
"fields": ["abc12345-e89b-12d3-a456-426614174003"],
"uuid_contacts": ["def67890-e89b-12d3-a456-426614174004"],
"operations": [
{
"id_opportunity_type": 1,
"comment": "Initial operation",
"items": [
{
"item_type": "crop",
"id_crop": 1,
"id_crop_variety": 2,
"quantity": 100,
"id_unit": 1,
"unit_value": 50.5,
"id_currency": 1
}
]
}
]
}

Request Fields:

  • action: Must be "create" (string, required)
  • uuid: Optional custom UUID for mobile sync (string, optional, UUID format)
  • name: Opportunity name (string, required, minimum 1 character)
  • uuid_account: Account UUID (string, optional, UUID format)
  • id_opportunity_type: Opportunity type ID (integer, required)
  • uuid_stage: Stage UUID (string, optional, UUID format)
  • tags: Array of tag IDs (array of integers, optional)
  • comment: Additional comments (string, optional)
  • fields: Array of field UUIDs (array of strings, optional)
  • uuid_contacts: Array of contact UUIDs (array of strings, optional)
  • operations: Array of operation objects (array, optional)

Response:

{
"code": 0,
"info": "Opportunity created",
"uuid": "123e4567-e89b-12d3-a456-426614174000",
"order": 1.5
}

Error Codes:

  • Code 1: "JSON required" - Missing request body
  • Code 3: "Action required" - Missing action field
  • Code 4: "Field does not exist" - Invalid field UUID provided
  • Code 5: "Stage not valid" - Invalid stage UUID or stage is inactive
  • Code 6: "Opportunity type not valid" - Invalid opportunity type ID

4. Update Opportunity

Update an existing opportunity.

Endpoint: POST /api/sales/opportunities/

Request:

{
"action": "update",
"uuid": "123e4567-e89b-12d3-a456-426614174000",
"name": "Updated Opportunity Name",
"stage_uuid": "789e0123-e89b-12d3-a456-426614174002",
"after_uuid": "abc12345-e89b-12d3-a456-426614174005",
"id_opportunity_state": 2,
"tags": [1, 3, 5],
"comment": "Updated comment",
"uuid_contacts": ["def67890-e89b-12d3-a456-426614174004"],
"operations": []
}

Request Fields:

  • action: Must be "update" (string, required)
  • uuid: Opportunity UUID (string, required, UUID format)
  • stage_uuid: New stage UUID (string, optional, UUID format)
  • after_uuid: UUID of opportunity to insert after (string, optional, null means first position)
  • name: New name (string, optional)
  • uuid_account: New account UUID (string, optional)
  • id_opportunity_type: New type ID (integer, optional)
  • id_opportunity_state: New state ID (integer, optional)
  • order: New order value (number, optional)
  • tags: New tags array (array of integers, optional)
  • id_loss_reason: Loss reason ID (integer, optional)
  • comment: New comment (string, optional)
  • fields: New fields array (array of strings, optional)
  • uuid_contacts: New contacts array (array of strings, optional)
  • operations: New operations array (array, optional, null deletes all)

Response:

{
"code": 0,
"info": "Opportunity updated",
"order": 2.5
}

Error Codes:

  • Code 1: "JSON required" - Missing request body
  • Code 2: "No fields to update" - No valid fields provided for update
  • Code 3: "Action required" - Missing action field
  • Code 4: "Field does not exist" - Invalid field UUID provided
  • Code 5: "Stage not valid" - Invalid stage UUID or stage is inactive
  • Code 6: "Opportunity type not valid" - Invalid opportunity type ID
  • Code 7: "Opportunity not found" - The specified opportunity UUID doesn't exist

5. Delete Opportunity

Delete an opportunity (soft delete). Only the owner can delete their opportunities.

Endpoint: POST /api/sales/opportunities/

Request:

{
"action": "delete",
"uuid": "123e4567-e89b-12d3-a456-426614174000"
}

Request Fields:

  • action: Must be "delete" (string, required)
  • uuid: Opportunity UUID (string, required, UUID format)

Response:

{
"code": 0,
"info": "Opportunity deleted"
}

Error Codes:

  • Code 1: "JSON required" - Missing request body
  • Code 3: "Action required" - Missing action field or invalid action
  • Code 7: "Opportunity not found" - The specified opportunity UUID doesn't exist
  • Code 3: "Only the owner can delete the opportunity" - User is not the owner

6. Get Opportunity Owners

Get all users in the workspace that can be opportunity owners.

Endpoint: GET /api/sales/opportunities/owners

Request:

  • No parameters required

Response:

{
"code": 0,
"data": [
{
"id": 123,
"first_name": "John",
"last_name": "Doe"
}
]
}

Operations Endpoints

7. Get Operations for Opportunity

Get all operations associated with an opportunity.

Endpoint: GET /api/sales/opportunities/operations

Request:

  • Query Parameters:
    • uuid_opportunity: Opportunity UUID (string, required)
    • page: Pagination cursor (string, optional)
    • limit: Number of results (integer, default: 15)

Response:

{
"data": [
{
"uuid": "op123456-e89b-12d3-a456-426614174000",
"id_opportunity_type": 1,
"comment": "Operation comment",
"creation_date": "2024-01-15T10:30:00",
"last_modified": "2024-01-20T15:45:00",
"items": [
{
"uuid": "item1234-e89b-12d3-a456-426614174001",
"item_type": "crop",
"id_crop": 1,
"crop_name": "Wheat",
"id_crop_variety": 2,
"crop_variety_name": "Winter Wheat",
"quantity": 100,
"id_unit": 1,
"unit_name": "kg",
"unit_value": 50.5,
"id_currency": 1
}
]
}
],
"next_page": "MTIz"
}

Error Codes:

  • Code 2: "uuid_opportunity required" - Missing uuid_opportunity parameter

8. Create Operation

Create a new operation for an opportunity.

Endpoint: POST /api/sales/opportunities/operations

Request:

{
"action": "create",
"uuid_opportunity": "123e4567-e89b-12d3-a456-426614174000",
"id_opportunity_type": 1,
"comment": "New operation",
"items": [
{
"item_type": "input",
"id_input": 5,
"quantity": 50,
"id_unit": 2,
"unit_value": 25.0,
"id_currency": 1
}
]
}

Response:

{
"code": 0,
"info": "Operation created",
"uuid": "op123456-e89b-12d3-a456-426614174000"
}

Error Codes:

  • Code 1: "JSON required" - Missing request body
  • Code 3: "Action required" - Missing action field

9. Update Operation

Update an existing operation.

Endpoint: POST /api/sales/opportunities/operations

Request:

{
"action": "update",
"uuid_opportunity": "123e4567-e89b-12d3-a456-426614174000",
"uuid_operation": "op123456-e89b-12d3-a456-426614174000",
"data": {
"id_opportunity_type": 2,
"comment": "Updated comment",
"items": []
}
}

Response:

{
"code": 0,
"info": "Operation updated"
}

Error Codes:

  • Code 1: "JSON required" - Missing request body
  • Code 3: "Action required" - Missing action field

10. Delete Operation

Delete an operation (soft delete).

Endpoint: POST /api/sales/opportunities/operations

Request:

{
"action": "delete",
"uuid_operation": "op123456-e89b-12d3-a456-426614174000"
}

Response:

{
"code": 0,
"info": "Operation deleted"
}

Error Codes:

  • Code 1: "JSON required" - Missing request body
  • Code 3: "Action required" - Missing action field

Notes Endpoints

11. Get Notes

Get all notes for an opportunity or account.

Endpoint: GET /api/sales/notes

Request:

  • Query Parameters:
    • entity_uuid: UUID of the entity (string, required)
    • entity_type: Type of entity - "opportunity" or "account" (string, required)

Response:

{
"notes": [
{
"uuid": "note1234-e89b-12d3-a456-426614174000",
"text": "Important note",
"creation_date": "2024-01-15T10:30:00",
"last_modified": "2024-01-20T15:45:00",
"owner": "John Doe"
}
]
}

Error Codes:

  • Code 2: "entity_uuid required" - Missing entity_uuid parameter
  • Code 2: "entity_type required" - Missing entity_type parameter
  • Code 3: "entity_type must be 'opportunity', or 'account'" - Invalid entity_type value

12. Create Note

Create a new note for an opportunity or account.

Endpoint: POST /api/sales/notes

Request:

{
"action": "create",
"entity_uuid": "123e4567-e89b-12d3-a456-426614174000",
"entity_type": "opportunity",
"text": "This is a new note"
}

Response:

{
"code": 0,
"info": "note created",
"uuid": "note1234-e89b-12d3-a456-426614174000"
}

Error Codes:

  • Code 1: "JSON required" - Missing request body
  • Code 3: "Action required" - Missing action field

13. Update Note

Update an existing note.

Endpoint: POST /api/sales/notes

Request:

{
"action": "update",
"note_uuid": "note1234-e89b-12d3-a456-426614174000",
"text": "Updated note text"
}

Response:

{
"code": 0,
"info": "note updated",
"uuid": "note1234-e89b-12d3-a456-426614174000"
}

Error Codes:

  • Code 1: "JSON required" - Missing request body
  • Code 3: "Action required" - Missing action field

14. Delete Note

Delete a note (soft delete).

Endpoint: POST /api/sales/notes

Request:

{
"action": "delete",
"note_uuid": "note1234-e89b-12d3-a456-426614174000"
}

Response:

{
"code": 0,
"info": "note deleted",
"uuid": "note1234-e89b-12d3-a456-426614174000"
}

Error Codes:

  • Code 1: "JSON required" - Missing request body
  • Code 3: "Action required" - Missing action field

Attachments Endpoints

15. Initialize Attachment

Initialize an attachment upload (calls internal API backend).

Endpoint: PUT /api/sales/attachments

Request:

{
"uuid": "attach123-e89b-12d3-a456-426614174000"
}

Response:

{
"url": "https://upload.url/...",
"data": {
"uuid": "attach123-e89b-12d3-a456-426614174000"
}
}

Error Codes:

  • Code 2: "uuid required" - Missing uuid field

16. Get Attachments

Get all attachments for an opportunity.

Endpoint: GET /api/sales/attachments

Request:

  • Query Parameters:
    • uuid_opportunity: Opportunity UUID (string, required)

Response:

{
"attachments": [
{
"uuid": "attach123-e89b-12d3-a456-426614174000",
"filename": "document.pdf",
"size_kb": 1024,
"user_id": 123,
"fecha_ini": "2024-01-15T10:30:00",
"uploaded": true
}
]
}

Error Codes:

  • Code 2: "uuid_opportunity required" - Missing uuid_opportunity parameter

17. Associate Attachment

Associate an attachment to an opportunity.

Endpoint: POST /api/sales/attachments

Request:

{
"action": "associate",
"uuid_opportunity": "123e4567-e89b-12d3-a456-426614174000",
"uuid_attachment": "attach123-e89b-12d3-a456-426614174000"
}

Response:

{
"code": 0,
"info": "attachment associated"
}

Error Codes:

  • Code 1: "JSON required" - Missing request body
  • Code 3: "Action required" - Missing action field

18. Dissociate Attachment

Remove an attachment from an opportunity.

Endpoint: POST /api/sales/attachments

Request:

{
"action": "dissociate",
"uuid_opportunity": "123e4567-e89b-12d3-a456-426614174000",
"uuid_attachment": "attach123-e89b-12d3-a456-426614174000"
}

Response:

{
"code": 0,
"info": "attachment dissociated"
}

Error Codes:

  • Code 1: "JSON required" - Missing request body
  • Code 3: "Action required" - Missing action field

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)
  • 403: Forbidden (insufficient permissions)
  • 429: Too Many Requests (rate limit exceeded)
  • 500: Internal Server Error

Permission Codes

All opportunities endpoints require specific permissions:

Permission CodeDescription
2020Create opportunities
2021Read/list opportunities and owners
2022Update opportunities
2023Delete opportunities
2040Create notes
2041Read notes
2042Update notes
2043Delete notes
2050Create/associate attachments
2051Read attachments
2053Delete/dissociate attachments

Business Rules

Opportunity States

  • 1: Open (Abierta) - Default state when creating
  • 2: Won (Ganada)
  • 3: Lost (Perdida)

Opportunity Types

  • 1: Purchase (Compra)
  • 2: Sale (Venta)
  • 3: Exchange (Canje)

Stage Management

  • Opportunities can be assigned to stages or left without stage ("Sin Etapa")
  • Use uuid_stage="null" or uuid_stage="0" to filter opportunities without stage
  • Moving opportunities between stages updates the order automatically
  • Order is managed using float-based system for efficient reordering

Ownership and Permissions

  • Only the owner can delete their opportunities
  • Users can see opportunities they own, opportunities from supervised users, and opportunities from collaborators
  • Permission validation is performed before all operations

Soft Delete

  • Opportunities, operations, notes, and attachments use soft delete (deleted_at timestamp)
  • Deleted items won't appear in list or get operations

Field Mapping

API FieldDatabase FieldDescription
uuiduuidOpportunity UUID
namenameOpportunity name
uuid_accountid_accountAccount reference
id_opportunity_typeid_opportunity_typeType ID
id_opportunity_stateid_opportunity_stateState ID
uuid_stageid_stage_opportunityStage reference
orderorderPosition order
start_datestart_dateCreation date
updated_atupdated_atLast update
deleted_atdeleted_atDeletion timestamp

Usage Examples

JavaScript/Fetch Example:

// List opportunities (Kanban view)
const response = await fetch('/api/sales/opportunities/', {
method: 'POST',
headers: {
'Authorization': 'Bearer ' + token,
'Content-Type': 'application/json'
},
body: JSON.stringify({
action: 'get',
limit: 15
})
});

// Create opportunity
const createResponse = await fetch('/api/sales/opportunities/', {
method: 'POST',
headers: {
'Authorization': 'Bearer ' + token,
'Content-Type': 'application/json'
},
body: JSON.stringify({
action: 'create',
name: 'New Opportunity',
id_opportunity_type: 1,
uuid_account: '123e4567-e89b-12d3-a456-426614174000'
})
});

// Update opportunity
const updateResponse = await fetch('/api/sales/opportunities/', {
method: 'POST',
headers: {
'Authorization': 'Bearer ' + token,
'Content-Type': 'application/json'
},
body: JSON.stringify({
action: 'update',
uuid: '123e4567-e89b-12d3-a456-426614174000',
name: 'Updated Name',
id_opportunity_state: 2
})
});