Quotation Management

Quotation Management API

The Quotation Management API allows you to manage quotations/estimates in your TaskIP CRM system. You can create, read, update, and delete quotations, convert them to invoices, and manage their approval workflow.

Endpoints Overview

MethodEndpointDescription
GET/api/public-v1/quotationGet all quotations
POST/api/public-v1/quotationCreate a new quotation
GET/api/public-v1/quotation/{id}Get a specific quotation
PUT/api/public-v1/quotation/{id}Update a quotation
DELETE/api/public-v1/quotation/{id}Delete a quotation
POST/api/public-v1/quotation/{id}/convert-to-invoiceConvert quotation to invoice
POST/api/public-v1/quotation/{id}/send-to-clientSend quotation to client via email
POST/api/public-v1/quotation/{id}/status-updateUpdate quotation status
POST/api/public-v1/quotation/publish/{id}Publish/unpublish quotation
GET/api/public-v1/quotation/{id}/downloadDownload quotation PDF
POST/api/public-v1/quotation/sent/{id}Send quotation to client (rate limited)
POST/api/public-v1/quotation/bulk-actionsPerform bulk operations

Get All Quotations

Retrieve a list of all quotations in your system.

GET /api/public-v1/quotation

Request Headers

X-Secret-Key: your-secret-key-here
Content-Type: application/json

Query Parameters

ParameterTypeRequiredDescription
pageintegerNoPage number for pagination (default: 1)
limitintegerNoNumber of quotations per page (default: 50)
searchstringNoSearch term for quotation number or client name
sortstringNoSort field (quotation_number, total_amount, created_at)
orderstringNoSort order (asc or desc)
statusstringNoFilter by status (draft, sent, accepted, rejected, expired)
client_idintegerNoFilter by client ID
date_fromstringNoFilter quotations from date (YYYY-MM-DD)
date_tostringNoFilter quotations to date (YYYY-MM-DD)

Example Request

curl -X GET "https://public-api.taskip.net/api/public-v1/quotation?page=1&limit=20&status=sent" \
  -H "X-Secret-Key: your-secret-key-here" \
  -H "Content-Type: application/json"

JavaScript Example

const response = await fetch('https://public-api.taskip.net/api/public-v1/quotation?page=1&limit=20', {
  method: 'GET',
  headers: {
    'X-Secret-Key': 'your-secret-key-here',
    'Content-Type': 'application/json'
  }
});
 
const quotations = await response.json();

Example Response

{
  "data": [
    {
      "id": 1,
      "quotation_no": "QUO-001",
      "generatedId": "QUO-2024-001",
      "slug": "abc123def456",
      "company": {
        "id": 15,
        "name": "Acme Corporation",
        "email": "billing@acme.com"
      },
      "folder_id": "5",
      "folder": {
        "id": 5,
        "name": "Q1 2024 Quotations"
      },
      "contact_id": 45,
      "contacts": {
        "id": 45,
        "first_name": "John",
        "last_name": "Smith",
        "email": "john@acme.com"
      },
      "subject": "Website Development Quotation",
      "up_payment_status": true,
      "up_payment_amount": "1000",
      "up_payment_type": "fixed",
      "turnaround_times": 30,
      "expire_date": "2024-02-14",
      "currency": "USD",
      "subtotal": 4500.00,
      "tax": [
        {
          "id": 1,
          "name": "VAT",
          "rate": 10,
          "amount": 450.00
        }
      ],
      "currentNote": {
        "id": "QUO-001",
        "note": "Payment Terms",
        "term": "50% upfront payment required"
      },
      "notes": [
        {
          "id": 1,
          "title": "Payment Terms",
          "description": "50% upfront payment required",
          "enable": true,
          "created_at": "2024-01-15T10:30:00Z",
          "updated_at": "2024-01-15T10:30:00Z"
        }
      ],
      "total": 4950.00,
      "items": [
        {
          "id": 1,
          "name": "Web Development Services",
          "qty": 1,
          "rate": 4500.00,
          "label": "Project"
        }
      ],
      "logo": {
        "id": 101,
        "url": "https://cdn.taskip.net/logos/company-logo.png",
        "thumbnail": "https://cdn.taskip.net/logos/company-logo-thumb.png"
      },
      "signature": null,
      "discount": 0,
      "discount_type": "fixed",
      "template": 1,
      "status": "draft",
      "publish": true,
      "activities": [],
      "reminders": {
        "enabled": true,
        "days_before": [7, 3, 1],
        "template": "default"
      },
      "created_by": {
        "id": 1,
        "name": "Admin User"
      },
      "updated_by": {
        "id": 1,
        "name": "Admin User"
      },
      "created_at": "2024-01-15T10:30:00Z",
      "updated_at": "2024-01-15T10:30:00Z",
      "deleted_at": null
    }
  ],
  "links": {
    "first": "https://public-api.taskip.net/api/public-v1/quotation?page=1",
    "last": "https://public-api.taskip.net/api/public-v1/quotation?page=2",
    "prev": null,
    "next": "https://public-api.taskip.net/api/public-v1/quotation?page=2"
  },
  "meta": {
    "current_page": 1,
    "from": 1,
    "last_page": 2,
    "path": "https://public-api.taskip.net/api/public-v1/quotation",
    "per_page": 20,
    "to": 20,
    "total": 25,
    "search": "website"
  }
}

Create a Quotation

Create a new quotation in your system.

POST /api/public-v1/quotation

Request Headers

X-Secret-Key: your-secret-key-here
Content-Type: application/json

Request Body

FieldTypeRequiredDescription
estimate_nostringNoEstimate number (max 191 characters)
contact_idintegerYesContact ID for the quotation
folder_idintegerNoFolder ID for organization
subjectstringYesQuotation subject (max 191 characters)
up_payment_statusintegerNoUpfront payment status (0 or 1)
up_payment_amountdecimalNoUpfront payment amount
up_payment_typestringNoUpfront payment type
turnaround_timesstringNoTurnaround time description
expire_datestringNoExpiration date (YYYY-MM-DD)
currencystringNo3-digit ISO currency code (default: USD)
statusstringNoStatus (draft, pending, etc.)
notestringNoInternal notes
terms_conditionstringNoTerms and conditions
itemsarrayYesArray of quotation items

Item Object Structure

FieldTypeRequiredDescription
descriptionstringYesItem description
quantitydecimalYesItem quantity
unit_pricedecimalYesPrice per unit

Example Request

curl -X POST "https://public-api.taskip.net/api/public-v1/quotation" \
  -H "X-Secret-Key: your-secret-key-here" \
  -H "Content-Type: application/json" \
  -d '{
    "estimate_no": "EST-2024-001",
    "contact_id": 15,
    "folder_id": 5,
    "subject": "Custom Website Development Quote",
    "up_payment_status": 1,
    "up_payment_amount": 2500.00,
    "up_payment_type": "percentage",
    "turnaround_times": "2-3 weeks",
    "expire_date": "2024-02-19",
    "currency": "USD",
    "status": "draft",
    "note": "Custom website development with SEO",
    "terms_condition": "50% upfront payment required",
    "items": [
      {
        "description": "Custom Website Development",
        "quantity": 1,
        "unit_price": 5000.00
      },
      {
        "description": "SEO Optimization",
        "quantity": 1,
        "unit_price": 800.00
      }
    ]
  }'

Python Example

import requests
 
headers = {
    'X-Secret-Key': 'your-secret-key-here',
    'Content-Type': 'application/json'
}
 
quotation_data = {
    "estimate_no": "EST-2024-001",
    "contact_id": 15,
    "folder_id": 5,
    "subject": "Custom Website Development Quote",
    "up_payment_status": 1,
    "up_payment_amount": 2500.00,
    "up_payment_type": "percentage",
    "turnaround_times": "2-3 weeks",
    "expire_date": "2024-02-19",
    "currency": "USD",
    "status": "draft",
    "note": "Custom website development with SEO",
    "terms_condition": "50% upfront payment required",
    "items": [
        {
            "description": "Custom Website Development",
            "quantity": 1,
            "unit_price": 5000.00
        },
        {
            "description": "SEO Optimization",
            "quantity": 1,
            "unit_price": 800.00
        }
    ]
}
 
response = requests.post(
    'https://public-api.taskip.net/api/public-v1/quotation',
    headers=headers,
    json=quotation_data
)
 
result = response.json()

Example Response

{
  "msg": "Quotation created successfully"
}

Get a Specific Quotation

Retrieve details of a specific quotation by ID.

GET /api/public-v1/quotation/{id}

Path Parameters

ParameterTypeRequiredDescription
idintegerYesQuotation ID

Example Request

curl -X GET "https://public-api.taskip.net/api/public-v1/quotation/26" \
  -H "X-Secret-Key: your-secret-key-here" \
  -H "Content-Type: application/json"

Example Response

{
  "id": 26,
  "uuid": "550e8400-e29b-41d4-a716-446655440000",
  "quotation_no": "QUO-2024-026",
  "generatedId": "QUO-2024-026",
  "subject": "Custom Website Development Quote",
  "contact_id": 15,
  "up_payment_status": 1,
  "up_payment_amount": "2500.00",
  "up_payment_type": "percentage",
  "turnaround_times": "2-3 weeks",
  "expire_date": "2024-02-19",
  "status": "draft",
  "currency": "USD",
  "note": "Custom website development with SEO",
  "terms_condition": "50% upfront payment required",
  "total": "5800.00",
  "sub_total": "5800.00",
  "tax": null,
  "discount": null,
  "folder_id": 5,
  "created_at": "2024-01-20T14:30:00.000000Z",
  "updated_at": "2024-01-20T14:30:00.000000Z",
  "company": {
    "id": 1,
    "name": "Taskip Agency",
    "email": "hello@taskip.com"
  },
  "contact": {
    "id": 15,
    "first_name": "John",
    "last_name": "Doe",
    "email": "john@acme.com",
    "phone": "+1-555-0100"
  },
  "folder": {
    "id": 5,
    "name": "Web Development Projects"
  },
  "items": [
    {
      "id": 45,
      "title": "Custom Website Development",
      "description": "Full stack website development",
      "quantity": "1",
      "price": "5000.00"
    },
    {
      "id": 46,
      "title": "SEO Optimization",
      "description": "Search engine optimization",
      "quantity": "1",
      "price": "800.00"
    }
  ],
  "activities": [
    {
      "id": 1,
      "log_name": "default",
      "description": "created",
      "subject_id": 26,
      "subject_type": "App\\Models\\Estimate",
      "causer_id": 1,
      "causer_type": "App\\Models\\User",
      "properties": {},
      "created_at": "2024-01-20T14:30:00.000000Z",
      "updated_at": "2024-01-20T14:30:00.000000Z"
    }
  ]
}

Update a Quotation

Update an existing quotation's information.

PUT /api/public-v1/quotation/{id}

Path Parameters

ParameterTypeRequiredDescription
idintegerYesQuotation ID to update

Request Body

Same fields as create quotation. All fields are optional - only include fields you want to update.

Example Request

curl -X PUT "https://public-api.taskip.net/api/public-v1/quotation/26" \
  -H "X-Secret-Key: your-secret-key-here" \
  -H "Content-Type: application/json" \
  -d '{
    "expire_date": "2024-03-20",
    "subject": "Updated Custom Website Development Quote",
    "turnaround_times": "3-4 weeks",
    "note": "Extended validity period - custom website with advanced features"
  }'

Example Response

{
  "msg": "Quotation updated successfully"
}

Delete a Quotation

Delete a specific quotation from your system.

DELETE /api/public-v1/quotation/{id}

Path Parameters

ParameterTypeRequiredDescription
idintegerYesQuotation ID to delete
⚠️

Warning: Deleting a quotation will permanently remove it and all associated data. This action cannot be undone.

Example Request

curl -X DELETE "https://public-api.taskip.net/api/public-v1/quotation/26" \
  -H "X-Secret-Key: your-secret-key-here"

Example Response

{
  "msg": "Quotation deleted successfully"
}

Convert Quotation to Invoice

Convert an accepted quotation into an invoice.

POST /api/public-v1/quotation/{id}/convert-to-invoice

Path Parameters

ParameterTypeRequiredDescription
idintegerYesQuotation ID to convert

Request Body

FieldTypeRequiredDescription
due_datestringYesInvoice due date (YYYY-MM-DD)
payment_termsstringNoPayment terms for the invoice

Example Request

curl -X POST "https://public-api.taskip.net/api/public-v1/quotation/25/convert-to-invoice" \
  -H "X-Secret-Key: your-secret-key-here" \
  -H "Content-Type: application/json" \
  -d '{
    "due_date": "2024-02-20",
    "payment_terms": "Net 30"
  }'

JavaScript Example

const conversionData = {
  due_date: "2024-02-20",
  payment_terms: "Net 30"
};
 
const response = await fetch('https://public-api.taskip.net/api/public-v1/quotation/25/convert-to-invoice', {
  method: 'POST',
  headers: {
    'X-Secret-Key': 'your-secret-key-here',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify(conversionData)
});
 
const result = await response.json();

Example Response

{
  "msg": "Quotation converted to invoice successfully"
}

Send Quotation to Client

Send quotation to client via email.

POST /api/public-v1/quotation/{id}/send-to-client

Path Parameters

ParameterTypeRequiredDescription
idintegerYesQuotation ID to send

Request Body

FieldTypeRequiredDescription
email_templatestringNoEmail template to use
custom_messagestringNoCustom message to include
cc_emailsarrayNoAdditional CC email addresses
send_copy_to_selfbooleanNoSend copy to sender (default: true)

Example Request

curl -X POST "https://public-api.taskip.net/api/public-v1/quotation/25/send-to-client" \
  -H "X-Secret-Key: your-secret-key-here" \
  -H "Content-Type: application/json" \
  -d '{
    "custom_message": "Please review the attached quotation for your project requirements.",
    "cc_emails": ["manager@company.com"],
    "send_copy_to_self": true
  }'

Example Response

{
  "msg": "Quotation sent to client successfully"
}

Update Quotation Status

Update the status of a quotation.

POST /api/public-v1/quotation/{id}/status-update

Path Parameters

ParameterTypeRequiredDescription
idintegerYesQuotation ID

Request Body

FieldTypeRequiredDescription
statusstringYesNew status (draft, sent, accepted, rejected, expired)
reasonstringNoReason for status change
notesstringNoAdditional notes

Example Request

curl -X POST "https://public-api.taskip.net/api/public-v1/quotation/25/status-update" \
  -H "X-Secret-Key: your-secret-key-here" \
  -H "Content-Type: application/json" \
  -d '{
    "status": "accepted",
    "reason": "Client approved via phone",
    "notes": "Client requested to start work immediately"
  }'

Example Response

{
  "msg": "Quotation status updated successfully"
}

Bulk Actions

Perform bulk operations on multiple quotations.

POST /api/public-v1/quotation/bulk-actions

Request Body

FieldTypeRequiredDescription
quotation_idsarrayYesArray of quotation IDs
actionstringYesAction to perform (delete, status_update, send_to_clients)
parametersobjectNoAdditional parameters for the action

Action-specific Parameters

For status_update action:

  • status: New status for all quotations
  • reason: Reason for status change

For send_to_clients action:

  • email_template: Email template to use
  • custom_message: Custom message for all emails

Example Request

curl -X POST "https://public-api.taskip.net/api/public-v1/quotation/bulk-actions" \
  -H "X-Secret-Key: your-secret-key-here" \
  -H "Content-Type: application/json" \
  -d '{
    "quotation_ids": [20, 21, 22, 23],
    "action": "status_update",
    "parameters": {
      "status": "expired",
      "reason": "Validity period ended"
    }
  }'

JavaScript Example

const bulkData = {
  quotation_ids: [20, 21, 22, 23],
  action: "send_to_clients",
  parameters: {
    email_template: "quotation_reminder",
    custom_message: "This is a reminder about your pending quotation."
  }
};
 
const response = await fetch('https://public-api.taskip.net/api/public-v1/quotation/bulk-actions', {
  method: 'POST',
  headers: {
    'X-Secret-Key': 'your-secret-key-here',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify(bulkData)
});
 
const result = await response.json();

Example Response

{
  "msg": "Bulk action completed successfully"
}

Error Responses

Common Error Codes

Status CodeError TypeDescription
400Bad RequestInvalid request data or missing required fields
401UnauthorizedInvalid or missing X-Secret-Key
404Not FoundQuotation not found
409ConflictQuotation cannot be modified in current status
422Validation ErrorRequest data failed validation
429Too Many RequestsRate limit exceeded

Example Error Response

{
  "success": false,
  "error": "Validation Error",
  "message": "The given data was invalid",
  "errors": {
    "client_id": ["The client id field is required."],
    "items": ["At least one item is required."],
    "valid_until": ["The valid until date must be after issue date."]
  },
  "status_code": 422
}

Response Schemas

Quotation Object

{
  "id": "integer",
  "quotation_number": "string",
  "client_id": "integer",
  "client_name": "string",
  "client_email": "string",
  "issue_date": "string (YYYY-MM-DD)",
  "valid_until": "string (YYYY-MM-DD)",
  "status": "string",
  "currency": "string",
  "subtotal": "decimal",
  "tax_rate": "decimal",
  "tax_amount": "decimal",
  "discount_amount": "decimal",
  "total_amount": "decimal",
  "notes": "string|null",
  "terms_conditions": "string|null",
  "items": "array",
  "created_at": "string (ISO 8601)",
  "updated_at": "string (ISO 8601)"
}

Quotation Item Object

{
  "id": "integer",
  "description": "string",
  "quantity": "decimal",
  "unit_price": "decimal",
  "line_total": "decimal"
}

Client Summary Object (in quotation details)

{
  "id": "integer",
  "name": "string",
  "email": "string",
  "phone": "string|null",
  "company": "string|null"
}

Best Practices

Quotation Creation

  1. Clear descriptions: Use detailed item descriptions for better client understanding
  2. Realistic validity periods: Set appropriate validity periods based on project complexity
  3. Professional presentation: Include comprehensive terms and conditions
  4. Accurate pricing: Double-check calculations before sending to clients

Workflow Management

  1. Status tracking: Use proper status progression (draft → sent → accepted/rejected)
  2. Client communication: Send quotations with personalized messages
  3. Follow-up: Track quotation status and follow up on pending quotations
  4. Conversion timing: Convert accepted quotations to invoices promptly

Data Management

  1. Regular cleanup: Archive or delete expired quotations
  2. Template usage: Create standardized quotation templates
  3. Backup important quotes: Keep copies of significant quotations
  4. Version control: Track changes when updating quotations
💡

Tip: Use the bulk actions endpoint to efficiently manage multiple quotations. This is particularly useful for updating statuses of expired quotations or sending reminder emails to multiple clients.


Publish/Unpublish Quotation

Publish or unpublish a quotation to make it visible to clients.

POST /api/public-v1/quotation/publish/{id}

Path Parameters

ParameterTypeRequiredDescription
idintegerYesQuotation ID to publish/unpublish

Request Body

FieldTypeRequiredDescription
publishbooleanYesTrue to publish, false to unpublish

Example Request

curl -X POST "https://public-api.taskip.net/api/public-v1/quotation/publish/25" \
  -H "X-Secret-Key: your-secret-key-here" \
  -H "Content-Type: application/json" \
  -d '{
    "publish": true
  }'

Example Response

{
  "success": true,
  "message": "Quotation published successfully",
  "data": {
    "id": 25,
    "quotation_number": "QUO-2024-025",
    "is_published": true,
    "published_at": "2024-01-26T14:30:00Z",
    "public_url": "https://public-api.taskip.net/quotation/view/abc123def456"
  }
}

Download Quotation PDF

Download a quotation as a PDF file.

GET /api/public-v1/quotation/{id}/download

Path Parameters

ParameterTypeRequiredDescription
idintegerYesQuotation ID to download

Example Request

curl -X GET "https://public-api.taskip.net/api/public-v1/quotation/25/download" \
  -H "X-Secret-Key: your-secret-key-here" \
  --output quotation_25.pdf

Response

Returns a PDF file with Content-Type: application/pdf header.


Send Quotation to Client (Rate Limited)

Send a quotation directly to the client via email with rate limiting.

⚠️

This endpoint is rate limited to 10 requests per minute to prevent spam.

POST /api/public-v1/quotation/sent/{id}

Path Parameters

ParameterTypeRequiredDescription
idintegerYesQuotation ID to send

Request Body

FieldTypeRequiredDescription
recipient_emailstringNoOverride recipient email (defaults to quotation client)
custom_messagestringNoCustom message to include in email
cc_emailsarrayNoAdditional CC email addresses
attach_pdfbooleanNoAttach PDF copy (default: true)

Example Request

curl -X POST "https://public-api.taskip.net/api/public-v1/quotation/sent/25" \
  -H "X-Secret-Key: your-secret-key-here" \
  -H "Content-Type: application/json" \
  -d '{
    "custom_message": "Please review the attached quotation for your project.",
    "cc_emails": ["manager@company.com"],
    "attach_pdf": true
  }'

Example Response

{
  "success": true,
  "message": "Quotation sent successfully",
  "data": {
    "quotation_id": 25,
    "sent_to": "client@example.com",
    "cc_emails": ["manager@company.com"],
    "sent_at": "2024-01-26T14:30:00Z",
    "email_tracking_id": "email_abc123def456"
  }
}