NAV
shell

CCUBE API v2 Reference

Overview

Base URLs: - Production: https://{tenant-subdomain}.inc.construction Replace {tenant-subdomain} with your tenant subdomain provided by CCUBE.

Conventions

Authentication

To authenticate, use this endpoint:

POST https://{tenant-subdomain}.inc.construction/users/sign_in

curl -X POST "https://{tenant-subdomain}.inc.construction/users/sign_in" \
  -H "Content-Type: application/json" \
  -d '{
    "user": {
      "email": "your.email@example.com",
      "password": "your_password"
    }
  }'

Success Response (200 OK):

{
  "user_token": "generated_token",
  "user_email": "your.email@example.com",
  "email": "your.email@example.com",
  "user_id": 1,
  "user_contact_id": 1
}

All subsequent API requests must include the Authorization header:

Authorization: Token YourToken,user_email=your.email@example.com

Users

Get All Users

curl "https://{tenant-subdomain}.inc.construction/api/v2/users" \
  -H 'Authorization: Token YourApiToken,user_email=YourEmail'

The above command returns JSON structured like this:

[
  {
    "id": 1,
    "email": "user1@example.com",
    "name": "User One",
    "role": "admin",
    "created_at": "2024-01-01T12:00:00Z",
    "updated_at": "2024-01-15T09:30:00Z"
  },
  {
    "id": 2,
    "email": "user2@example.com",
    "name": "User Two",
    "role": "user",
    "created_at": "2024-01-02T10:00:00Z",
    "updated_at": "2024-01-16T08:45:00Z"
  }
]

This endpoint retrieves all Users.

HTTP Request

GET https://{tenant-subdomain}.inc.construction/api/v2/users

Query Parameters

Parameter Default Description
page 1 Page number to retrieve
per_page 20 Number of results per page

Get Specific User

This endpoint retrieves a specific User.

HTTP Request

GET https://{tenant-subdomain}.inc.construction/api/v2/users/{id}

URL Parameters

Parameter Description
ID The ID of the User to retrieve
curl "https://{tenant-subdomain}.inc.construction/api/v2/users/1" \
  -H 'Authorization: Token YourApiToken,user_email=YourEmail'

The above command returns JSON structured like this:

{
  "id": 1,
  "email": "user1@example.com",
  "given_name": "User",
  "family_name": "One"
}

Create a New User

This endpoint to create a new User.

HTTP Request

POST https://{tenant-subdomain}.inc.construction/api/v2/users

Body Parameters

Parameter Type Required Description
user[email] string yes User's email address
user[password] string yes User's password (min 8 chars)
user[password_confirmation] string yes Must match password
user[user_type] string yes Either "full" or "limited"
user[contact_id] integer no Associated contact ID
user[role_ids][] array[integer] yes Array of role IDs
user[given_name] string no User's first name
user[family_name] string no User's last name
user[suspended] boolean no Account status (default: false)
user[super_user] boolean no Super user status (default: false)
user[paid_tenant] boolean no Paid tenant status
user[dunning_tenant] boolean no Dunning status
user[trial] boolean no Trial status
user[demo] boolean no Demo account status
user[paid_user] boolean no Paid user status
curl 'https://{tenant-subdomain}.inc.construction/api/v2/users' -X POST \
  -H 'Authorization: Token YourApiToken,user_email=YourEmail' \
  -H 'Content-Type: application/json' \
  --data-raw '{
    "user": {
      "email": "newuser@example.com",
      "password": "password123",
      "password_confirmation": "password123",
      "user_type": "full",
      "contact_id": 1234,
      "role_ids": [1],
      "given_name": "John",
      "family_name": "Doe",
      "suspended": false,
      "super_user": false,
      "paid_tenant": false,
      "dunning_tenant": false,
      "trial": false,
      "demo": false,
      "paid_user": false
    }
  }'

The above command returns JSON structured like this:

{
  "id": 3,
  "email": "newuser@example.com",
  "role": "user",
  "name": "New User",
  "suspended": false,
  "current_sign_in_at": "2023-10-01T12:00:00Z",
  "last_sign_in_at": "2023-09-30T12:00:00Z",
  "given_name": "New",
  "family_name": "User"
}

Delete a User

This endpoint deletes a specific User.

HTTP Request

DELETE https://{tenant-subdomain}.inc.construction/api/v2/users/{id}

URL Parameters

Parameter Description
ID The ID of the User to delete
curl 'https://{tenant-subdomain}.inc.construction/api/v2/users/{id}' -X DELETE \
-H 'Authorization: Token YourApiToken,user_email=YourEmail' \
-H 'Content-Type: application/json'

The above command returns JSON structured like this:

{"message": "User deleted successfully"}

Update a User

Endpoint: PUT /api/v2/users/{id}

Description: This endpoint updates an existing user’s details by their ID.

Body Parameters (Update)

Parameter Type Required Description
user[email] string no New email address
user[given_name] string no First name
user[family_name] string no Last name
user[suspended] boolean no Account status
user[user_type] string no Either "full" or "limited"
user[contact_id] integer no Associated contact ID
user[role_ids][] array[integer] no Role assignments

CURL Request

curl 'https://{tenant-subdomain}.inc.construction/api/v2/users/{id}' -X PUT \
  -H 'Authorization: Token YourApiToken,user_email=YourEmail' \
  -H 'Content-Type: application/json' \
  --data-raw '{
    "user": {
      "email": "updated@example.com",
      "given_name": "John",
      "family_name": "Doe",
      "suspended": false,
      "user_type": "full",
      "contact_id": 1234,
      "role_ids": [1]
    }
  }'

The above command returns JSON structured like this:

{
  "id": 1,
  "email": "updated@example.com",
  "given_name": "John",
  "family_name": "Doe"
}

Projects

Get All Projects

curl "https://{tenant-subdomain}.inc.construction/api/v2/projects" \
  -H 'Authorization: Token YourToken,user_email=YourEmail'

The above command returns JSON structured like this:

[
  {
    "id": 1,
    "status": "Active",
    "stage": { "id": 2, "name": "Active" },
    "number": "P-001",
    "work_start": "2024-01-01",
    "work_end": "2024-12-31",
    "external_id": null,
    "building_id": 10,
    "call_notes": null,
    "client": { "name": "Client Co", "email": "client@example.com", "phone": "+11234567890" },
    "workflow_id": 3,
    "work_type": { "id": 5, "name": "Roofing" },
    "property_type": { "id": 7, "name": "Residential" },
    "communication_status": { "id": 1, "name": "Open" },
    "created_at": "2024-01-01T00:00:00Z",
    "updated_at": "2024-01-05T00:00:00Z"
  }
]

This endpoint retrieves all Projects.

HTTP Request

GET https://{tenant-subdomain}.inc.construction/api/v2/projects

Query Parameters

Parameter Default Description
page 1 Page number to retrieve
per_page 20 Number of results per page

Get Specific Project

This endpoint retrieves a specific Project.

HTTP Request

GET https://{tenant-subdomain}.inc.construction/api/v2/projects/{id}

URL Parameters

Parameter Description
ID The ID of the Project to retrieve
curl "https://{tenant-subdomain}.inc.construction/api/v2/projects/1" \
  -H 'Authorization: Token YourApiToken,user_email=YourEmail' 

The above command returns JSON structured like this:

{
  "id": 1,
  "number": "P-001",
  "status": "Active",
  "stage": { "id": 2, "name": "Active" },
  "work_start": "2024-01-01",
  "work_end": "2024-12-31",
  "external_id": null,
  "building_id": 10,
  "call_notes": null,
  "work_type": { "id": 5, "name": "Roofing" },
  "property_type": { "id": 7, "name": "Residential" },
  "communication_status": { "id": 1, "name": "Open" },
  "client": { "name": "Client Co", "email": "client@example.com", "phone": "+11234567890" },
  "address": { "id": 99, "street": "123 Main St", "city": "City", "state": "ST", "zip": "12345", "country": "USA" }
}

Create a New Project

This endpoint creates a new Project.

HTTP Request

POST https://{tenant-subdomain}.inc.construction/api/v2/projects

Body Parameters

Parameter Type Required Description
project[name] string yes Project title
project[number] string yes Unique project number/reference
project[client_id] integer yes Associated client ID
project[manager_id] integer yes Project manager ID
project[work_start] date no Project start date (YYYY-MM-DD)
project[work_end] date no Project end date (YYYY-MM-DD)
project[stage_id] integer no Current stage ID (pipeline stage)
project[work_type_id] integer no Work type ID
project[property_type_id] integer no Property type ID (FR: type de propriété)
project[communication_status_id] integer no Communication status ID
project[call_notes] string no Call notes (FR: demande)
curl -X POST "https://{tenant-subdomain}.inc.construction/api/v2/projects" \
  -H 'Authorization: Token YourToken,user_email=YourEmail' \
  -H "Content-Type: application/json" \
  -d '{
    "project": {
      "name": "Project Name",
      "number": "P-001",
      "client_id": 1,
      "manager_id": 1,
      "work_start": "2024-01-01",
      "work_end": "2024-12-31",
      "stage_id": 2,
      "work_type_id": 5,
      "property_type_id": 7,
      "communication_status_id": 1,
      "call_notes": "Left voicemail; follow-up tomorrow"
    }
  }'

The above command returns JSON structured like this:

{
  "id": 1,
  "name": "project 1"
}

Delete a Project

This endpoint deletes a specific Project.

HTTP Request

DELETE https://{tenant-subdomain}.inc.construction/api/v2/projects/{id}

URL Parameters

curl 'https://{tenant-subdomain}.inc.construction/api/v2/projects/{id}' -X DELETE \
-H 'Authorization: Token YourApiToken,user_email=YourEmail' \
-H 'Content-Type: application/json'

The above command returns JSON structured like this:

{
  "message": "Project deleted"
}

Update a Project

Endpoint: PUT /api/v2/projects/{id}

Description: This endpoint updates an existing project's details by ID.

Body Parameters

Parameter Type Required Description
project[name] string no Project title
project[number] string no Project reference
project[client_id] integer no Associated client ID
project[manager_id] integer no Project manager ID
project[work_start] date no Start date (YYYY-MM-DD)
project[work_end] date no End date (YYYY-MM-DD)
project[stage_id] integer no Stage ID
project[work_type_id] integer no Work type ID
project[property_type_id] integer no Property type ID
project[communication_status_id] integer no Communication status ID
project[call_notes] string no Call notes

CURL Request

curl 'https://{tenant-subdomain}.inc.construction/api/v2/projects/{id}' -X PUT \
  -H 'Authorization: Token YourApiToken,user_email=YourEmail' \
  -H 'Content-Type: application/json' \
  --data-raw '{
    "project": {
      "name": "Updated Project",
      "number": "P-001",
      "client_id": 1,
      "manager_id": 1,
      "work_start": "2024-02-01",
      "work_end": "2024-12-15",
      "stage_id": 3,
      "work_type_id": 6,
      "property_type_id": 8,
      "communication_status_id": 2,
      "call_notes": "Client confirmed meeting 08/20"
    }
  }'

The above command returns JSON structured like this:

{
  "id": 1,
  "name": "project 1",
  "number": "23",
  "updated_at": "2024-08-28T19:27:32.094-04:00"
}

Get Communication Statuses

This endpoint retrieves all available communication statuses for projects.

HTTP Request

GET https://{tenant-subdomain}.inc.construction/api/v2/projects/communication_statuses

curl "https://{tenant-subdomain}.inc.construction/api/v2/projects/communication_statuses" \
  -H 'Authorization: Token YourToken,user_email=YourEmail'

The above command returns JSON structured like this:

[
  {
    "id": 1,
    "name": "New Inquiry",
    "value": "new_inquiry",
    "position": 1,
    "is_first": true,
    "is_last": false,
    "type": "Projects/CommunicationStatus"
  },
  {
    "id": 2,
    "name": "Called Back",
    "value": "called_back",
    "position": 2,
    "is_first": false,
    "is_last": false,
    "type": "Projects/CommunicationStatus"
  },
  {
    "id": 3,
    "name": "Scheduled",
    "value": "scheduled",
    "position": 3,
    "is_first": false,
    "is_last": true,
    "type": "Projects/CommunicationStatus"
  }
]

Get Work Types

This endpoint retrieves all available work types for projects.

HTTP Request

GET https://{tenant-subdomain}.inc.construction/api/v2/projects/work_types

curl "https://{tenant-subdomain}.inc.construction/api/v2/projects/work_types" \
  -H 'Authorization: Token YourToken,user_email=YourEmail'

The above command returns JSON structured like this:

[
  {
    "id": 1,
    "name": "Borne Résidentielle",
    "value": "borne_residentielle",
    "position": 1,
    "type": "Projects/WorkType"
  },
  {
    "id": 2,
    "name": "Borne Commerciale",
    "value": "borne_commerciale",
    "position": 2,
    "type": "Projects/WorkType"
  },
  {
    "id": 3,
    "name": "Multi Logements",
    "value": "multi_logements",
    "position": 3,
    "type": "Projects/WorkType"
  },
  {
    "id": 4,
    "name": "Autres travaux électriques",
    "value": "autres_travaux_electriques",
    "position": 4,
    "type": "Projects/WorkType"
  }
]

Get Project Stages

This endpoint retrieves all available stages for projects based on the default workflow.

HTTP Request

GET https://{tenant-subdomain}.inc.construction/api/v2/projects/stages

curl "https://{tenant-subdomain}.inc.construction/api/v2/projects/stages" \
  -H 'Authorization: Token YourToken,user_email=YourEmail'

The above command returns JSON structured like this:

[
  {
    "id": 1,
    "name": "call",
    "workflow_id": 1,
    "previous_steps": [],
    "next_steps": [2, 6, 8]
  },
  {
    "id": 2,
    "name": "quote",
    "workflow_id": 1,
    "previous_steps": [1],
    "next_steps": [3, 6, 7]
  },
  {
    "id": 3,
    "name": "work",
    "workflow_id": 1,
    "previous_steps": [2],
    "next_steps": [4, 7]
  }
]

Quotes

Get All Quotes

GET /api/v2/quotes shell curl "https://{tenant-subdomain}.inc.construction/api/v2/quotes" \ -H 'Authorization: Token YourToken,user_email=YourEmail'

The above command returns JSON structured like this:

[
  {
    "id": 1,
    "project_id": 12,
    "client_id": 34,
    "number": "Q-001",
    "quoted_total": 3500.0,
    "created_at": "2024-01-01T00:00:00Z",
    "updated_at": "2024-01-02T00:00:00Z",
    "status": "Draft",
    "subtotal": 3200.0,
    "external_id": null,
    "client": { "id": 34, "name": "Client Co", "email": "client@example.com", "phone": "+11234567890" }
  }
]

This endpoint retrieves all Quotes.

HTTP Request

GET https://{tenant-subdomain}.inc.construction/api/v2/quotes

Query Parameters

Parameter Default Description
page 1 Page number to retrieve
per_page 20 Number of results per page

Get Specific Quote

This endpoint retrieves a specific Quote.

HTTP Request

GET https://{tenant-subdomain}.inc.construction/api/v2/quotes/{id}

URL Parameters

Parameter Description
ID The ID of the Quote to retrieve
curl "https://{tenant-subdomain}.inc.construction/api/v2/quotes/1" \
  -H 'Authorization: Token YourApiToken,user_email=YourEmail'

The above command returns JSON structured like this:

{
  "id": 4,
  "number": "Q-1002",
  "status": "Approved",
  "external_id": null,
  "client": { "name": "Client Co", "email": "client@example.com", "phone": "+11234567890" }
}

Create a New Quote

This endpoint to create a new Quote.

HTTP Request

POST https://{tenant-subdomain}.inc.construction/api/v2/quotes

Body Parameters

Parameter Type Required Description
quote[number] string yes Quote number/reference
quote[description] string no Quote details/notes
quote[project_id] integer yes Associated project ID
quote[department_id] integer yes Department ID
quote[quote_type] string yes Quote type (e.g., standard)
quote[terms] string no Payment terms
quote[title] string no Quote title
curl -X POST "https://{tenant-subdomain}.inc.construction/api/v2/quotes" \
  -H 'Authorization: Token YourToken,user_email=YourEmail' \
  -H "Content-Type: application/json" \
  -d '{
    "quote": {
      "number": "Q-001",
      "description": "Description",
      "project_id": 1,
      "department_id": 1,
      "quote_type": "standard",
      "terms": "Payment terms",
      "title": "Quote title"
    }
  }'

The above command returns JSON structured like this:

{
  "id": 36,
  "number": "Q-1033",
  "status": "Draft",
  "external_id": null
}

Delete a Quote

This endpoint deletes a specific Quote.

HTTP Request

DELETE https://{tenant-subdomain}.inc.construction/api/v2/quotes/{id}

URL Parameters

curl 'https://{tenant-subdomain}.inc.construction/api/v2/quotes/{id}' -X DELETE \
-H 'Authorization: Token YourApiToken,user_email=YourEmail' \
-H 'Content-Type: application/json'

The above command returns JSON structured like this:

{"message": "Quote deleted successfully"}

Update a Quote

Endpoint: PUT /api/v2/quotes/{id}

Description: This endpoint updates an existing quote's details by ID.

CURL Request

curl 'https://{tenant-subdomain}.inc.construction/api/v2/quotes/{id}' -X PUT \
  -H 'Authorization: Token YourApiToken,user_email=YourEmail' \
  -H 'Content-Type: application/json' \
  --data-raw '{
    "quote": {
      "number": "Q-001",
      "description": "Updated description",
      "project_id": 1,
      "department_id": 1,
      "quote_type": "standard"
    }
  }'

The above command returns JSON structured like this:

{
  "id": 164,
  "name": "1154-S1157",
  "description": "roof fix"
}

Invoices

Get All Invoices

GET /api/v2/invoices

curl "https://{tenant-subdomain}.inc.construction/api/v2/invoices" \
  -H 'Authorization: Token YourToken,user_email=YourEmail'

The above command returns JSON structured like this:

[
  {
    "id": 1,
    "number": "INV-1000",
    "issue_date": "2024-01-01",
    "due_date": "2024-01-31",
    "project_id": 1,
    "client_id": 1,
    "subtotal": 1000.0,
    "total": 1000.0,
    "paid_total": 800.0,
    "balance": 200.0
  }
]

This endpoint retrieves all Invoices.

HTTP Request

GET https://{tenant-subdomain}.inc.construction/api/v2/invoices

### Query Parameters

Pagination

⚠️ Coming Soon

Parameter Default Description
page 1 you can specify which page to get
per_page 20 number of results per page

Get Specific Invoice

This endpoint retrieves a specific Invoice.

HTTP Request

GET https://{tenant-subdomain}.inc.construction/api/v2/invoices/{id}

URL Parameters

Parameter Description
ID The ID of the Invoice to retrieve
curl "https://{tenant-subdomain}.inc.construction/api/v2/invoices/1" \
  -H 'Authorization: Token YourApiToken,user_email=YourEmail'

The above command returns JSON structured like this:

{
  "id": 1,
  "number": "INV-1000",
  "full_number": "2024-INV-1000",
  "issue_date": "2024-01-01",
  "due_date": "2024-01-31",
  "project_id": 1,
  "client_id": 1,
  "status": "Approved",
  "external_id": null,
  "subtotal": 1000.0,
  "tax1_rate": 0.0,
  "tax2_rate": 0.0,
  "tax1_amount": 0.0,
  "tax2_amount": 0.0,
  "total": 1000.0,
  "paid_total": 1000.0,
  "balance": 0.0,
  "subject": "Invoice subject",
  "description": "Invoice description",
  "terms": null,
  "created_at": "2024-01-01T00:00:00Z",
  "updated_at": "2024-01-01T00:00:00Z",
  "paid_on": "2024-01-15",
  "estimator_id": null,
  "is_credit": false,
  "client": { "name": "Client Co", "email": "client@example.com", "phone": "+11234567890" },
  "lines": [
    {
      "id": 11,
      "material": "Shingles - 3-tab",
      "description": "Roof replacement - materials",
      "quantity": 20,
      "unit_price": 25.0,
      "rate": null,
      "total": 500.0,
      "position": 1
    },
    {
      "id": 12,
      "material": null,
      "description": "Labor",
      "quantity": 10,
      "unit_price": 50.0,
      "rate": null,
      "total": 500.0,
      "position": 2
    }
  ]
}

Notes: - paid_total represents the total of all payments applied to this invoice (no individual payments listed here). - subtotal, tax1_amount, tax2_amount, and total are numeric amounts; tax1_rate and tax2_rate are decimal rates (e.g., 0.099 for 9.9%). - client_id corresponds to the Party (client/contact) associated to the invoice; some UIs may label this as Party ID. - lines[].material is optional; use it to store the material reference/label. lines[].rate is reserved for future use; when not applicable, it may be null. - Balance = total - paid_total.

Line item fields returned in lines[]: - id: integer - material: string or null (optional) - description: string - quantity: number - unit_price: number - rate: number or null (reserved for future rate usage) - total: number (quantity x unit_price, adjusted by rate if applicable) - position: integer (ordering)

Create a New Invoice

This endpoint creates a new Invoice.

HTTP Request

POST https://{tenant-subdomain}.inc.construction/api/v2/invoices

Body Parameters

Parameter Type Required Description
invoice[number] string yes Invoice number/reference
invoice[subject] string yes Invoice subject/title
invoice[description] string no Invoice description
invoice[client_id] integer yes Client ID (aka Party ID)
invoice[project_id] integer yes Project ID
invoice[issue_date] date yes Issue date (YYYY-MM-DD)
invoice[due_date] date no Due date (YYYY-MM-DD)
invoice[lines_attributes][] array[object] no Line items to create; each item supports: material (string, optional), description (string), quantity (number), unit_price (number), rate (number, optional), position (integer, optional)
curl -X POST "https://{tenant-subdomain}.inc.construction/api/v2/invoices" \
  -H 'Authorization: Token YourToken,user_email=YourEmail' \
  -H "Content-Type: application/json" \
  -d '{
    "invoice": {
      "number": "INV-001",
      "subject": "Invoice subject",
      "description": "Details",
      "client_id": 1,
      "project_id": 1,
      "issue_date": "2024-01-01",
      "due_date": "2024-01-31",
      "lines_attributes": [
        {"material": "Shingles - 3-tab", "description": "Materials", "quantity": 20, "unit_price": 25.0, "position": 1},
        {"description": "Labor", "quantity": 10, "unit_price": 50.0, "position": 2}
      ]
    }
  }'

The above command returns JSON structured like this:

{
  "id": 67,
  "number": "INV-011",
  "full_number": "2024-INV-011",
  "issue_date": "2024-01-01",
  "due_date": "2024-01-31",
  "project_id": 1,
  "client_id": 1,
  "status": "Draft",
  "external_id": null,
  "subtotal": 1000.0,
  "tax1_rate": 0.0,
  "tax2_rate": 0.0,
  "tax1_amount": 0.0,
  "tax2_amount": 0.0,
  "total": 1000.0,
  "paid_total": 0.0,
  "balance": 1000.0,
  "subject": "Invoice subject",
  "description": "Details",
  "terms": null,
  "created_at": "2024-01-01T00:00:00Z",
  "updated_at": "2024-01-01T00:00:00Z",
  "paid_on": null,
  "estimator_id": null,
  "is_credit": false,
  "client": { "name": "Client Co", "email": "client@example.com", "phone": "+11234567890" },
  "lines": [
    { "id": 1, "material": "Shingles - 3-tab", "description": "Materials", "quantity": 20, "unit_price": 25.0, "rate": null, "total": 500.0, "position": 1 },
    { "id": 2, "material": null, "description": "Labor", "quantity": 10, "unit_price": 50.0, "rate": null, "total": 500.0, "position": 2 }
  ]
}

Delete a Invoice

This endpoint deletes a specific Invoice.

HTTP Request

DELETE https://{tenant-subdomain}.inc.construction/api/v2/invoices/{id}

URL Parameters

curl 'https://{tenant-subdomain}.inc.construction/api/v2/invoices/{id}' -X DELETE \
-H 'Authorization: Token YourApiToken,user_email=YourEmail' \
-H 'Content-Type: application/json'

The above command returns JSON structured like this:

{
  "message": "Invoice deleted"
}

Update a Invoice

Endpoint: PUT /api/v2/invoices/{id}

Description: This endpoint updates an existing invoice’s details by ID.

CURL Request

curl 'https://{tenant-subdomain}.inc.construction/api/v2/invoices/{id}' -X PUT \
  -H 'Authorization: Token YourApiToken,user_email=YourEmail' \
  -H 'Content-Type: application/json' \
  --data-raw '{
    "invoice": {
      "number": "INV-001",
      "subject": "Updated subject",
      "client_id": 1,
      "project_id": 1
    }
  }'

The above command returns JSON structured like this:

{
  "id": 6,
  "number": "1",
  "subject": "1"
}

Purchase Orders

Get All Purchase Orders

HTTP Request

GET https://{tenant-subdomain}.inc.construction/api/v2/purchase_orders

This endpoint retrieves all Purchase Orders.

Query Parameters

Pagination

⚠️ Coming Soon

Parameter Default Description
page 1 you can specify which page to get
per_page 20 number of results per page
curl "https://{tenant-subdomain}.inc.construction/api/v2/purchase_orders" \
  -H 'Authorization: Token YourApiToken,user_email=YourEmail'

The above command returns JSON structured like this:

[
  {
    "id": 1,
    "project_id": 22,
    "number": "PO-1001",
    "description": "Complete kitchen renovation.",
    "expected_start": "2024-02-01",
    "created_at": "2024-01-10T00:00:00Z",
    "updated_at": "2024-01-12T00:00:00Z",
    "external_id": null
  },
  {
    "id": 2,
    "project_id": 23,
    "number": "PO-1002",
    "description": "Bathroom remodeling.",
    "expected_start": null,
    "created_at": "2024-01-11T00:00:00Z",
    "updated_at": "2024-01-13T00:00:00Z",
    "external_id": null
  }
]

Get Specific Purchase Order

This endpoint retrieves a specific Purchase Order.

HTTP Request

GET https://{tenant-subdomain}.inc.construction/api/v2/purchase_orders/ID

URL Parameters

Parameter Description
ID The ID of the Purchase order to retrieve
curl "https://{tenant-subdomain}.inc.construction/api/v2/purchase_orders/1" \
  -H 'Authorization: Token YourApiToken,user_email=YourEmail'

The above command returns JSON structured like this:

{
  "id": 1,
  "number": "PO-1011",
  "external_id": null
}

Create a New Purchase Order

This endpoint to create a new Purchase Order.

HTTP Request

POST https://{tenant-subdomain}.inc.construction/api/v2/purchase_orders

Body Parameters

Parameter Type Required Description
purchase_order[number] string yes Purchase order number/reference
purchase_order[description] string no Purchase order description
purchase_order[department_id] integer yes Department ID
curl 'https://{tenant-subdomain}.inc.construction/api/v2/purchase_orders' -X POST \
-H 'Authorization: Token YourApiToken,user_email=YourEmail' \
-H 'Content-Type: application/json' \
--data-raw '{
   "purchase_order": {
    "number": "PO-001",
    "description": "Purchase order description",
    "department_id": 1
    }
}'

The above command returns JSON structured like this:

{
  "id": 1,
  "number": "PO-1011",
  "description": "Purchase order description",
  "external_id": null
}

Delete a Purchase Order

This endpoint deletes a specific Purchase Order.

HTTP Request

DELETE https://{tenant-subdomain}.inc.construction/api/v2/purchase_orders/{id}

URL Parameters

curl 'https://{tenant-subdomain}.inc.construction/api/v2/purchase_orders/{id}' -X DELETE \
-H 'Authorization: Token YourApiToken,user_email=YourEmail' \
-H 'Content-Type: application/json'

The above command returns JSON structured like this:

{
  "id": 1,
  "number": "1011"
}

Update a Purchase Order

Endpoint: PUT /api/v2/purchase_orders/{id}

Description: This endpoint updates an existing purchase order's details by ID.

CURL Request

curl 'https://{tenant-subdomain}.inc.construction/api/v2/purchase_orders/{id}' -X PUT \
-H 'Authorization: Token YourApiToken,user_email=YourEmail' \
-H 'Content-Type: application/json' \
--data-raw '{
"purchase_order": {
    "number": "PO-001",
    "description": "Updated description",
    "department_id": 1
  }
}'

Work Orders

Get All Work Orders

curl "https://{tenant-subdomain}.inc.construction/api/v2/work_orders" \
  -H 'Authorization: Token YourApiToken,user_email=YourEmail'

The above command returns JSON structured like this:

[
  {
    "id": 1,
    "project_id": 50,
    "number": "WO-1001",
    "created_at": "2024-01-10T00:00:00Z",
    "updated_at": "2024-01-12T00:00:00Z",
    "external_id": null
  },
  {
    "id": 2,
    "project_id": 51,
    "number": "WO-1002",
    "created_at": "2024-01-11T00:00:00Z",
    "updated_at": "2024-01-13T00:00:00Z",
    "external_id": null
  }
]

This endpoint retrieves all Work Orders.

HTTP Request

GET https://{tenant-subdomain}.inc.construction/api/v2/work_orders

Query Parameters

Pagination

⚠️ Coming Soon

Parameter Default Description
page 1 you can specify which page to get
per_page 20 number of results per page

Get Specific Work Order

This endpoint retrieves a specific Work Order.

HTTP Request

GET https://{tenant-subdomain}.inc.construction/api/v2/work_orders/ID

URL Parameters

Parameter Description
ID The ID of the Work order to retrieve
curl "https://{tenant-subdomain}.inc.construction/api/v2/work_orders/1" \
  -H 'Authorization: Token YourApiToken,user_email=YourEmail'
{
  "id": 1,
  "name": "WO-1001",
  "external_id": null
}

Create a New Work Order

This endpoint to create a new Work Order.

HTTP Request

POST https://{tenant-subdomain}.inc.construction/api/v2/work_orders

Body Parameters

Parameter Type Required Description
work_order[number] string yes Work order number/reference
work_order[description] string yes Work details/notes
work_order[department_id] integer yes Department ID
work_order[start_date] date no Start date (YYYY-MM-DD)
work_order[end_date] date no End date (YYYY-MM-DD)
curl 'https://{tenant-subdomain}.inc.construction/api/v2/work_orders' -X POST \
  -H 'Authorization: Token YourApiToken,user_email=YourEmail' \
  -H 'Content-Type: application/json' \
  --data-raw '{
    "work_order": {
      "number": "WO-001",
      "description": "Description",
      "department_id": 1,
      "start_date": "2024-01-01",
      "end_date": "2024-01-31"
    }
  }'
{
    "id": 1,
    "number": "WO-001",
    "description": "Work order description"
}

Delete a Work Orders

This endpoint deletes a specific Work Order.

HTTP Request

DELETE https://{tenant-subdomain}.inc.construction/api/v2/work_orders/{id}

URL Parameters

curl 'https://{tenant-subdomain}.inc.construction/api/v2/work_orders/{id}' -X DELETE \
-H 'Authorization: Token YourApiToken,user_email=YourEmail' \
-H 'Content-Type: application/json'


Update a Work Orders

Endpoint: PUT /api/v2/work_orders/{id}

Description: This endpoint updates an existing Work Order details by ID.

CURL Request

curl 'https://{tenant-subdomain}.inc.construction/api/v2/work_orders/{id}' -X PUT \
  -H 'Authorization: Token YourApiToken,user_email=YourEmail' \
  -H 'Content-Type: application/json' \
  --data-raw '{
    "work_order": {
      "number": "WO-001",
      "description": "Updated description",
      "department_id": 1
    }
  }'

Parties (contacts)

Get All Parties

curl "https://{tenant-subdomain}.inc.construction/api/v2/parties" \
  -H 'Authorization: Token YourApiToken,user_email=YourEmail'

The above command returns JSON structured like this:

[
  {
    "id": 1,
    "name": "Example Company",
    "type": "company",
    "addresses": [
      {
        "street": "123 Main St",
        "city": "Example City",
        "state": "EX",
        "zip": "12345",
        "country": "USA"
      }
    ]
  }
]

This endpoint retrieves all Parties.

HTTP Request

GET https://{tenant-subdomain}.inc.construction/api/v2/parties

Query Parameters

Pagination

⚠️ Coming Soon

Parameter Default Description
type null Filter by party type (building, company, contact)
subtype null Filter by party subtype
role null Filter by party role
# Role-based filters:

/api/v2/parties?role=employee    # Gets employee contacts
/api/v2/parties?role=supplier    # Gets both supplier contacts and companies
/api/v2/parties?role=client      # Gets both client contacts and companies



# Type-based filters:

/api/v2/parties?type=building    # Gets all buildings
/api/v2/parties?type=company     # Gets all companies
/api/v2/parties?type=contact     # Gets all contacts



Subtype-based filters (using the SUBTYPES arrays from your models):

/api/v2/parties?subtype=supplier   # Gets entities with supplier subtype
/api/v2/parties?subtype=client     # Gets entities with client subtype
/api/v2/parties?subtype=contact    # Gets entities with contact subtype
/api/v2/parties?subtype=employee   # Gets entities with employee subtype




# Type and Subtype combinations:

/api/v2/parties?type=contact&subtype=supplier    # Gets only contact-type suppliers
/api/v2/parties?type=company&subtype=client      # Gets only company-type clients



# Multiple subtypes (using comma separation):

/api/v2/parties?subtype=supplier,client          # Gets entities that are both suppliers and clients
/api/v2/parties?type=contact&subtype=employee,supplier  # Gets contacts that are both employees and suppliers

Create Party

Body Parameters

Parameter Type Required Description
party[name] string yes Party name
party[type] string yes One of: Crm::Parties::Contact, Crm::Parties::Company, Crm::Parties::Building
party[first_name] string conditional Required when type is Contact
party[last_name] string conditional Required when type is Contact
party[addresses_attributes][] array[object] no Nested addresses
addresses_attributes[][street] string no Street
addresses_attributes[][city] string no City
addresses_attributes[][state] string no State/province
addresses_attributes[][zip] string no Postal/ZIP code
addresses_attributes[][country] string no Country
party[phones_attributes][] array[object] no Nested phones
phones_attributes[][value] string no Phone number
phones_attributes[][type] string no e.g., office, mobile
party[emails_attributes][] array[object] no Nested emails
emails_attributes[][value] string no Email address
curl -X POST "https://{tenant-subdomain}.inc.construction/api/v2/parties" \
  -H 'Authorization: Token YourToken,user_email=YourEmail' \
  -H "Content-Type: application/json" \
  -d '{
    "party": {
      "name": "Company Name",
      "type": "Crm::Parties::Contact",
      "first_name": "John",
      "last_name": "Doe",
      "addresses_attributes": [
        {
          "street": "123 Main St",
          "city": "Example City",
          "state": "EX",
          "zip": "12345"
        }
      ],
      "phones_attributes": [
        {
          "value": "+1234567890",
          "type": "office"
        }
      ],
      "emails_attributes": [
        {
          "value": "contact@example.com"
        }
      ]
    }
  }'

The above command returns JSON structured like this:

{
  "id": 1,
  "name": "Example Company",
  "type": "Crm::Parties::Contact"
}

Update Party

curl -X PUT "https://{tenant-subdomain}.inc.construction/api/v2/parties/1" \
  -H 'Authorization: Token YourToken,user_email=YourEmail' \
  -H "Content-Type: application/json" \
  -d '{
    "party": {
      "name": "Updated Company Name"
    }
  }'

Delete Party

curl "https://{tenant-subdomain}.inc.construction/api/v2/parties/1" -X DELETE \
  -H 'Authorization: Token YourApiToken,user_email=YourEmail'

Contact Information

Create Phone

Body Parameters

Parameter Type Required Description
phone[value] string yes Phone number in international format if possible
phone[type] string no e.g., office, mobile, home
curl -X POST "https://{tenant-subdomain}.inc.construction/api/v2/phones" \
  -H 'Authorization: Token YourToken,user_email=YourEmail' \
  -H "Content-Type: application/json" \
  -d '{
    "phone": {
      "value": "+1234567890",
      "type": "office"
    }
  }'

Create Email

Body Parameters

Parameter Type Required Description
email[value] string yes Email address
curl -X POST "https://{tenant-subdomain}.inc.construction/api/v2/emails" \
  -H 'Authorization: Token YourToken,user_email=YourEmail' \
  -H "Content-Type: application/json" \
  -d '{
    "email": {
      "value": "contact@example.com"
    }
  }'

Create Address

Body Parameters

Parameter Type Required Description
address[street] string yes Street
address[city] string yes City
address[state] string yes State/province
address[zip] string yes Postal/ZIP code
address[country] string no Country
curl -X POST "https://{tenant-subdomain}.inc.construction/api/v2/addresses" \
  -H 'Authorization: Token YourToken,user_email=YourEmail' \
  -H "Content-Type: application/json" \
  -d '{
    "address": {
      "street": "123 Main St",
      "city": "Example City",
      "state": "EX",
      "zip": "12345",
      "country": "USA"
    }
  }'

Notes

Get All Notes

curl "https://{tenant-subdomain}.inc.construction/api/v2/notes?page=1&per_page=20" \
  -H 'Authorization: Token YourApiToken,user_email=YourEmail'

The above command returns JSON structured like this:

[
  {
    "id": 1,
    "notable_type": "Project",
    "notable_id": 123,
    "body": "Example note text",
    "created_by_id": 45,
    "created_at": "2024-01-01T00:00:00Z",
    "updated_at": "2024-01-02T00:00:00Z"
  }
]

This endpoint retrieves all Notes.

HTTP Request

GET https://{tenant-subdomain}.inc.construction/api/v2/notes

Query Parameters

Parameter Default Description
page 1 Page number to retrieve
per_page 20 Number of results per page
notable_type Filter by parent type (Project, Quote, Invoice, WorkOrder, PurchaseOrder)
notable_id Filter by parent ID

Get Specific Note

This endpoint retrieves a specific Note.

HTTP Request

GET https://{tenant-subdomain}.inc.construction/api/v2/notes/{id}

URL Parameters

Parameter Description
id The ID of the Note to retrieve
curl "https://{tenant-subdomain}.inc.construction/api/v2/notes/1" \
  -H 'Authorization: Token YourApiToken,user_email=YourEmail'

Returns JSON like:

{
  "id": 1,
  "notable_type": "Project",
  "notable_id": 123,
  "body": "Example note text",
  "created_by_id": 45,
  "created_at": "2024-01-01T00:00:00Z",
  "updated_at": "2024-01-02T00:00:00Z"
}

Create a New Note

HTTP Request

POST https://{tenant-subdomain}.inc.construction/api/v2/notes

Body Parameters

Parameter Type Required Description
note[notable_type] string yes Parent entity type (Project, Quote, Invoice, WorkOrder, PurchaseOrder)
note[notable_id] integer yes Parent entity ID
note[body] string yes Note text/body
curl 'https://{tenant-subdomain}.inc.construction/api/v2/notes' -X POST \
  -H 'Authorization: Token YourApiToken,user_email=YourEmail' \
  -H 'Content-Type: application/json' \
  --data-raw '{
    "note": {
      "notable_type": "Project",
      "notable_id": 123,
      "body": "Kickoff scheduled for Friday"
    }
  }'

Returns JSON structured like this:

{
  "id": 777,
  "notable_type": "Project",
  "notable_id": 123,
  "body": "Kickoff scheduled for Friday",
  "created_by_id": 45,
  "created_at": "2024-01-03T10:30:00Z",
  "updated_at": "2024-01-03T10:30:00Z"
}

Update a Note

Endpoint: PUT /api/v2/notes/{id}

Body Parameters

Parameter Type Required Description
note[body] string yes New note text/body

CURL Request

curl 'https://{tenant-subdomain}.inc.construction/api/v2/notes/{id}' -X PUT \
  -H 'Authorization: Token YourApiToken,user_email=YourEmail' \
  -H 'Content-Type: application/json' \
  --data-raw '{
    "note": {
      "body": "Updated note text"
    }
  }'

Delete a Note

HTTP Request

DELETE https://{tenant-subdomain}.inc.construction/api/v2/notes/{id}

curl 'https://{tenant-subdomain}.inc.construction/api/v2/notes/{id}' -X DELETE \
  -H 'Authorization: Token YourApiToken,user_email=YourEmail'

Errors

CCUBE API uses conventional HTTP status codes to indicate the success or failure of an API request. Errors are returned as JSON.

Example error response:

{
  "error": {
    "code": "unauthorized",
    "message": "Invalid or expired token",
    "details": null
  }
}
Status Meaning
400 Bad Request — Your request is invalid (e.g., malformed JSON, missing required parameter).
401 Unauthorized — Missing or invalid credentials. Ensure Authorization header is set: Authorization: Token <token>,user_email=<email>.
403 Forbidden — You do not have permission to perform this action.
404 Not Found — The requested resource does not exist.
405 Method Not Allowed — The HTTP method is not supported for this endpoint.
406 Not Acceptable — You requested a format that isn't JSON.
409 Conflict — The request could not be completed due to a resource conflict.
410 Gone — The requested resource is no longer available.
422 Unprocessable Entity — Validation failed; check details for field errors.
429 Too Many Requests — You have exceeded the rate limit.
500 Internal Server Error — We had a problem with our server. Try again later.
503 Service Unavailable — We're temporarily offline for maintenance. Try again later.