🚀 HomaNode API Documentation

High-performance REST API for database operations.

Introduction

HomaNode API provides a simple interface to perform CRUD operations on your database. All requests and responses use JSON format.

Authentication

All API requests require two parameters for authentication:

Parameter Type Description
PortalCode integer Your unique portal identifier
Token string Authentication token (UUID format)

Getting Your Credentials

To use HomaNode API, you need to obtain your PortalCode and Token from HomaCRM.com. Follow these steps:

Step 1: Register on HomaCRM.com

Visit HomaCRM.com and create an account if you don't have one already.

Step 2: Create CRM Access

After logging in, you need to create a new CRM access or use an existing one:

Step 3: Add to Services List

Once your CRM access is created, make sure it appears in your services list. If it's not there, add it to your services.

Step 4: Get Your Credentials

To retrieve your Token and PortalCode:

  1. Find your service in the services list
  2. Click on the Admin icon (</>) next to your service
  3. A modal window will open
  4. In the modal, you will see:
    • Token: Your authentication token (UUID format)
    • PortalCode: Your unique portal identifier (numeric)

Note: The PortalCode is also visible on your services page, but the Token is only available in the admin modal.

Example Credentials

Your credentials will look like this:

⚠️ Important: Keep your Token secure and never share it publicly. Treat it like a password.

Base URL

https://endpointplus.homais.com/homanode

Alternative endpoints:

GET - Select Data

GET /homanode?PortalCode={code}&Token={token}&table={table}

Query Parameters

Parameter Type Required Description
PortalCode integer Required Portal identifier
Token string Required Authentication token
table string Required Table name to query
pageNo integer Optional Page number (default: 1)
pageSize integer Optional Records per page (default: 100)
queryCommand string Optional SQL WHERE clause filter

Example Request

GET /homanode?PortalCode=10016025&Token=E36A7402-9FCE-4F37-94D1-66B965FAF5A9&table=product&pageSize=10

Success Response

[
  {
    "ID": 1,
    "Title": "Product Name",
    "Price": 100000,
    "PortalCode": 10016025
  },
  {
    "ID": 2,
    "Title": "Another Product",
    "Price": 200000,
    "PortalCode": 10016025
  }
]

POST - Insert Record

POST /homanode?PortalCode={code}&Token={token}&table={table}&updateCommand=true

Request Body (JSON)

{
  "Title": "New Product",
  "Price": 150000,
  "Category": 1
}

Note: Do NOT include ID field for insert operations.

Success Response

[
  {
    "success": true,
    "code": 201,
    "message": "Inserted successfully.",
    "id": 123
  }
]

POST - Update Record

POST /homanode?PortalCode={code}&Token={token}&table={table}&updateCommand=true

Request Body (JSON)

{
  "ID": 123,
  "Title": "Updated Product Name",
  "Price": 180000
}

Note: Include ID field to update an existing record.

Success Response

[
  {
    "success": true,
    "code": 200,
    "message": "Updated successfully.",
    "id": 123
  }
]

POST - Delete Record

POST /homanode?PortalCode={code}&Token={token}&table={table}&updateCommand=true

Delete by ID

{
  "ID": 123,
  "DeleteOrder": true
}

Delete by Condition

{
  "DeleteOrder": true,
  "deleteCondition": "Status = 0 AND CreatedDate < '2024-01-01'"
}

Success Response

[
  {
    "success": true,
    "code": 200,
    "message": "Record deleted successfully.",
    "id": 123
  }
]

Available Tables

Table Name Aliases Description
productware, waresingleProducts / Inventory items
warecategory-Product categories
warehouse-Warehouses
wareunit-Units of measure
contactlist-Customers / Contacts
contactcategory-Contact categories
invoiceheader-Invoice headers
invoicebody-Invoice line items
blogpost-Blog posts / Content (new portals)
blogcategory-Blog categories (new portals)
blogpost_old-Blog posts / Wiki (legacy portals)
blogcategory_old-Blog categories (legacy portals)
customeraddress-Customer addresses
cdn-Attachments / Files
warehouselogswhlogs, whlogWarehouse logs
warehousesheetswhsheets, whsheetWarehouse sheets
financedocsdocs, findocsFinancial documents
financedocitemsdocitems, findocitemsFinancial document items
urls-Short links
urlclicks-Short link visitors

cURL Examples

Get Products

curl "https://endpointplus.homais.com/homanode?PortalCode=10016025&Token=YOUR_TOKEN&table=product&pageSize=10"

Insert Product

curl -X POST "https://endpointplus.homais.com/homanode?PortalCode=10016025&Token=YOUR_TOKEN&table=product&updateCommand=true" \
  -H "Content-Type: application/json" \
  -d '{"Title": "New Product", "Price": 100000}'

Update Product

curl -X POST "https://endpointplus.homais.com/homanode?PortalCode=10016025&Token=YOUR_TOKEN&table=product&updateCommand=true" \
  -H "Content-Type: application/json" \
  -d '{"ID": 123, "Title": "Updated Title"}'

Delete Product

curl -X POST "https://endpointplus.homais.com/homanode?PortalCode=10016025&Token=YOUR_TOKEN&table=product&updateCommand=true" \
  -H "Content-Type: application/json" \
  -d '{"ID": 123, "DeleteOrder": true}'

JavaScript Example

const BASE_URL = 'https://endpointplus.homais.com/homanode';
const PORTAL_CODE = '10016025';
const TOKEN = 'YOUR_TOKEN';

// Get products with error handling
async function getProducts() {
  try {
    const response = await fetch(
      BASE_URL + '?' + new URLSearchParams({
        PortalCode: PORTAL_CODE,
        Token: TOKEN,
        table: 'product',
        pageSize: '10'
      })
    );
    
    if (!response.ok) {
      throw new Error('HTTP error! status: ' + response.status);
    }
    
    const products = await response.json();
    console.log('Products:', products);
    return products;
  } catch (error) {
    console.error('Error fetching products:', error);
    throw error;
  }
}

// Insert product
async function insertProduct(title, price) {
  try {
    const response = await fetch(
      BASE_URL + '?' + new URLSearchParams({
        PortalCode: PORTAL_CODE,
        Token: TOKEN,
        table: 'product',
        updateCommand: 'true'
      }),
      {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ Title: title, Price: price })
      }
    );
    
    const result = await response.json();
    if (result[0]?.success) {
      console.log('Product inserted:', result[0].id);
      return result[0];
    } else {
      throw new Error(result[0]?.message || 'Insert failed');
    }
  } catch (error) {
    console.error('Error inserting product:', error);
    throw error;
  }
}

// Update product
async function updateProduct(id, title, price) {
  try {
    const response = await fetch(
      BASE_URL + '?' + new URLSearchParams({
        PortalCode: PORTAL_CODE,
        Token: TOKEN,
        table: 'product',
        updateCommand: 'true'
      }),
      {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ ID: id, Title: title, Price: price })
      }
    );
    
    const result = await response.json();
    return result[0];
  } catch (error) {
    console.error('Error updating product:', error);
    throw error;
  }
}

// Delete product
async function deleteProduct(id) {
  try {
    const response = await fetch(
      BASE_URL + '?' + new URLSearchParams({
        PortalCode: PORTAL_CODE,
        Token: TOKEN,
        table: 'product',
        updateCommand: 'true'
      }),
      {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ ID: id, DeleteOrder: true })
      }
    );
    
    const result = await response.json();
    return result[0];
  } catch (error) {
    console.error('Error deleting product:', error);
    throw error;
  }
}

// Usage
getProducts();
insertProduct('New Product', 100000);
updateProduct(123, 'Updated Product', 180000);
deleteProduct(123);

TypeScript Example

interface ApiResponse {
  success: boolean;
  code: number;
  message: string;
  id?: number;
}

interface Product {
  ID: number;
  Title: string;
  Price: number;
  PortalCode: number;
}

class HomaNodeAPI {
  private baseUrl: string;
  private portalCode: string;
  private token: string;

  constructor(baseUrl: string, portalCode: string, token: string) {
    this.baseUrl = baseUrl;
    this.portalCode = portalCode;
    this.token = token;
  }

  private async request(method: string, table: string, params: Record = {}, body?: any): Promise {
    const queryParams = new URLSearchParams({
      PortalCode: this.portalCode,
      Token: this.token,
      table,
      ...params
    });

    const options: RequestInit = {
      method,
      headers: {
        'Content-Type': 'application/json'
      }
    };

    if (body) {
      options.body = JSON.stringify(body);
    }

    const response = await fetch(this.baseUrl + '?' + queryParams, options);
    
    if (!response.ok) {
      throw new Error('HTTP error! status: ' + response.status);
    }

    return response.json();
  }

  async getRecords(table: string, pageNo: number = 1, pageSize: number = 100, queryCommand?: string): Promise {
    const params: Record = {
      pageNo: pageNo.toString(),
      pageSize: pageSize.toString()
    };
    
    if (queryCommand) {
      params.queryCommand = queryCommand;
    }

    return this.request('GET', table, params);
  }

  async insertRecord(table: string, data: Record): Promise {
    const result = await this.request('POST', table, { updateCommand: 'true' }, data);
    return result[0];
  }

  async updateRecord(table: string, id: number, data: Record): Promise {
    return this.insertRecord(table, { ...data, ID: id });
  }

  async deleteRecord(table: string, id: number): Promise {
    return this.insertRecord(table, { ID: id, DeleteOrder: true });
  }
}

// Usage
const api = new HomaNodeAPI(
  'https://endpointplus.homais.com/homanode',
  '10016025',
  'YOUR_TOKEN'
);

// Get products
const products: Product[] = await api.getRecords('product', 1, 10);

// Insert product
const insertResult = await api.insertRecord('product', {
  Title: 'New Product',
  Price: 100000
});

// Update product
const updateResult = await api.updateRecord('product', 123, {
  Title: 'Updated Product',
  Price: 180000
});

// Delete product
const deleteResult = await api.deleteRecord('product', 123);

Python Example

import requests
from typing import Optional, Dict, List, Any

class HomaNodeAPI:
    def __init__(self, base_url: str, portal_code: str, token: str):
        self.base_url = base_url
        self.portal_code = portal_code
        self.token = token
        self.session = requests.Session()
    
    def _get_params(self, table: str, **kwargs) -> Dict[str, Any]:
        params = {
            "PortalCode": self.portal_code,
            "Token": self.token,
            "table": table
        }
        params.update(kwargs)
        return params
    
    def get_products(self, table: str = "product", page_no: int = 1, 
                     page_size: int = 100, query_command: Optional[str] = None) -> List[Dict]:
        """Get records from a table"""
        params = self._get_params(table, pageNo=page_no, pageSize=page_size)
        if query_command:
            params["queryCommand"] = query_command
        
        try:
            response = self.session.get(self.base_url, params=params)
            response.raise_for_status()
            return response.json()
        except requests.exceptions.RequestException as e:
            print(f"Error fetching products: {e}")
            raise
    
    def insert_record(self, table: str, data: Dict[str, Any]) -> Dict[str, Any]:
        """Insert a new record"""
        params = self._get_params(table, updateCommand="true")
        
        try:
            response = self.session.post(
                self.base_url,
                params=params,
                json=data
            )
            response.raise_for_status()
            result = response.json()
            if result and result[0].get("success"):
                return result[0]
            else:
                raise Exception(result[0].get("message", "Insert failed"))
        except requests.exceptions.RequestException as e:
            print(f"Error inserting record: {e}")
            raise
    
    def update_record(self, table: str, record_id: int, data: Dict[str, Any]) -> Dict[str, Any]:
        """Update an existing record"""
        data["ID"] = record_id
        return self.insert_record(table, data)
    
    def delete_record(self, table: str, record_id: Optional[int] = None, 
                     delete_condition: Optional[str] = None) -> Dict[str, Any]:
        """Delete a record by ID or condition"""
        data = {"DeleteOrder": True}
        if record_id:
            data["ID"] = record_id
        elif delete_condition:
            data["deleteCondition"] = delete_condition
        else:
            raise ValueError("Either record_id or delete_condition must be provided")
        
        return self.insert_record(table, data)

# Usage
api = HomaNodeAPI(
    base_url="https://endpointplus.homais.com/homanode",
    portal_code="10016025",
    token="YOUR_TOKEN"
)

# Get products
products = api.get_products(table="product", page_size=10)

# Insert product
result = api.insert_record("product", {
    "Title": "New Product",
    "Price": 100000
})

# Update product
result = api.update_record("product", 123, {
    "Title": "Updated Product",
    "Price": 180000
})

# Delete product
result = api.delete_record("product", record_id=123)

PHP Example

<?php
class HomaNodeAPI {
    private $baseUrl;
    private $portalCode;
    private $token;
    
    public function __construct($baseUrl, $portalCode, $token) {
        $this->baseUrl = $baseUrl;
        $this->portalCode = $portalCode;
        $this->token = $token;
    }
    
    private function makeRequest($method, $table, $params = [], $data = null) {
        $url = $this->baseUrl . "?" . http_build_query(array_merge([
            "PortalCode" => $this->portalCode,
            "Token" => $this->token,
            "table" => $table
        ], $params));
        
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        
        if ($method === "POST") {
            curl_setopt($ch, CURLOPT_POST, true);
            if ($data !== null) {
                curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
                curl_setopt($ch, CURLOPT_HTTPHEADER, [
                    "Content-Type: application/json"
                ]);
            }
        }
        
        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $error = curl_error($ch);
        curl_close($ch);
        
        if ($error) {
            throw new Exception("cURL Error: " . $error);
        }
        
        $result = json_decode($response, true);
        if ($httpCode >= 400) {
            throw new Exception("HTTP Error {$httpCode}: " . ($result[0]["message"] ?? "Unknown error"));
        }
        
        return $result;
    }
    
    public function getRecords($table, $pageNo = 1, $pageSize = 100, $queryCommand = null) {
        $params = ["pageNo" => $pageNo, "pageSize" => $pageSize];
        if ($queryCommand) {
            $params["queryCommand"] = $queryCommand;
        }
        return $this->makeRequest("GET", $table, $params);
    }
    
    public function insertRecord($table, $data) {
        $params = ["updateCommand" => "true"];
        return $this->makeRequest("POST", $table, $params, $data);
    }
    
    public function updateRecord($table, $id, $data) {
        $data["ID"] = $id;
        return $this->insertRecord($table, $data);
    }
    
    public function deleteRecord($table, $id = null, $deleteCondition = null) {
        $data = ["DeleteOrder" => true];
        if ($id !== null) {
            $data["ID"] = $id;
        } elseif ($deleteCondition !== null) {
            $data["deleteCondition"] = $deleteCondition;
        } else {
            throw new InvalidArgumentException("Either ID or deleteCondition must be provided");
        }
        return $this->insertRecord($table, $data);
    }
}

// Usage
$api = new HomaNodeAPI(
    "https://endpointplus.homais.com/homanode",
    "10016025",
    "YOUR_TOKEN"
);

try {
    // Get products
    $products = $api->getRecords("product", 1, 10);
    
    // Insert product
    $result = $api->insertRecord("product", [
        "Title" => "New Product",
        "Price" => 100000
    ]);
    
    // Update product
    $result = $api->updateRecord("product", 123, [
        "Title" => "Updated Product",
        "Price" => 180000
    ]);
    
    // Delete product
    $result = $api->deleteRecord("product", 123);
} catch (Exception $e) {
    echo "Error: " . $e->getMessage();
}
?>

PHP with Guzzle HTTP Client

<?php
require 'vendor/autoload.php';

use GuzzleHttp\Client;

$client = new Client([
    'base_uri' => 'https://endpointplus.homais.com/homanode',
]);

$portalCode = "10016025";
$token = "YOUR_TOKEN";

// Get products
$response = $client->get('', [
    'query' => [
        'PortalCode' => $portalCode,
        'Token' => $token,
        'table' => 'product',
        'pageSize' => 10
    ]
]);
$products = json_decode($response->getBody(), true);

// Insert product
$response = $client->post('', [
    'query' => [
        'PortalCode' => $portalCode,
        'Token' => $token,
        'table' => 'product',
        'updateCommand' => 'true'
    ],
    'json' => [
        'Title' => 'New Product',
        'Price' => 100000
    ]
]);
$result = json_decode($response->getBody(), true);

// Update product
$response = $client->post('', [
    'query' => [
        'PortalCode' => $portalCode,
        'Token' => $token,
        'table' => 'product',
        'updateCommand' => 'true'
    ],
    'json' => [
        'ID' => 123,
        'Title' => 'Updated Product Name',
        'Price' => 180000
    ]
]);
$result = json_decode($response->getBody(), true);

// Delete product
$response = $client->post('', [
    'query' => [
        'PortalCode' => $portalCode,
        'Token' => $token,
        'table' => 'product',
        'updateCommand' => 'true'
    ],
    'json' => [
        'ID' => 123,
        'DeleteOrder' => true
    ]
]);
$result = json_decode($response->getBody(), true);
?>

C# Example

using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;

public class HomaNodeAPI
{
    private readonly HttpClient _httpClient;
    private readonly string _baseUrl;
    private readonly string _portalCode;
    private readonly string _token;

    public HomaNodeAPI(string baseUrl, string portalCode, string token)
    {
        _baseUrl = baseUrl;
        _portalCode = portalCode;
        _token = token;
        _httpClient = new HttpClient();
    }

    public async Task<List<Dictionary<string, object>>> GetRecordsAsync(
        string table, int pageNo = 1, int pageSize = 100, string queryCommand = null)
    {
        var queryParams = $"?PortalCode={_portalCode}&Token={_token}&table={table}&pageNo={pageNo}&pageSize={pageSize}";
        if (!string.IsNullOrEmpty(queryCommand))
            queryParams += $"&queryCommand={Uri.EscapeDataString(queryCommand)}";

        var response = await _httpClient.GetAsync(_baseUrl + queryParams);
        response.EnsureSuccessStatusCode();
        
        var json = await response.Content.ReadAsStringAsync();
        return JsonSerializer.Deserialize<List<Dictionary<string, object>>>(json);
    }

    public async Task<Dictionary<string, object>> InsertRecordAsync(string table, Dictionary<string, object> data)
    {
        var queryParams = $"?PortalCode={_portalCode}&Token={_token}&table={table}&updateCommand=true";
        var json = JsonSerializer.Serialize(data);
        var content = new StringContent(json, Encoding.UTF8, "application/json");

        var response = await _httpClient.PostAsync(_baseUrl + queryParams, content);
        response.EnsureSuccessStatusCode();

        var resultJson = await response.Content.ReadAsStringAsync();
        var result = JsonSerializer.Deserialize<List<Dictionary<string, object>>>(resultJson);
        return result[0];
    }

    public async Task<Dictionary<string, object>> UpdateRecordAsync(string table, int id, Dictionary<string, object> data)
    {
        data["ID"] = id;
        return await InsertRecordAsync(table, data);
    }

    public async Task<Dictionary<string, object>> DeleteRecordAsync(string table, int? id = null, string deleteCondition = null)
    {
        var data = new Dictionary<string, object> { ["DeleteOrder"] = true };
        if (id.HasValue)
            data["ID"] = id.Value;
        else if (!string.IsNullOrEmpty(deleteCondition))
            data["deleteCondition"] = deleteCondition;
        else
            throw new ArgumentException("Either id or deleteCondition must be provided");

        return await InsertRecordAsync(table, data);
    }
}

// Usage
var api = new HomaNodeAPI(
    "https://endpointplus.homais.com/homanode",
    "10016025",
    "YOUR_TOKEN"
);

// Get products
var products = await api.GetRecordsAsync("product", pageSize: 10);

// Insert product
var result = await api.InsertRecordAsync("product", new Dictionary<string, object>
{
    ["Title"] = "New Product",
    ["Price"] = 100000
});

// Update product
result = await api.UpdateRecordAsync("product", 123, new Dictionary<string, object>
{
    ["Title"] = "Updated Product",
    ["Price"] = 180000
});

// Delete product
result = await api.DeleteRecordAsync("product", id: 123);

C# with RestSharp

using RestSharp;
using System.Collections.Generic;

public class HomaNodeClient
{
    private readonly RestClient _client;
    private readonly string _portalCode;
    private readonly string _token;

    public HomaNodeClient(string baseUrl, string portalCode, string token)
    {
        _client = new RestClient(baseUrl);
        _portalCode = portalCode;
        _token = token;
    }

    public List<Dictionary<string, object>> GetRecords(string table, int pageNo = 1, int pageSize = 100)
    {
        var request = new RestRequest("", Method.Get);
        request.AddQueryParameter("PortalCode", _portalCode);
        request.AddQueryParameter("Token", _token);
        request.AddQueryParameter("table", table);
        request.AddQueryParameter("pageNo", pageNo.ToString());
        request.AddQueryParameter("pageSize", pageSize.ToString());

        var response = _client.Execute<List<Dictionary<string, object>>>(request);
        return response.Data;
    }

    public Dictionary<string, object> InsertRecord(string table, Dictionary<string, object> data)
    {
        var request = new RestRequest("", Method.Post);
        request.AddQueryParameter("PortalCode", _portalCode);
        request.AddQueryParameter("Token", _token);
        request.AddQueryParameter("table", table);
        request.AddQueryParameter("updateCommand", "true");
        request.AddJsonBody(data);

        var response = _client.Execute<List<Dictionary<string, object>>>(request);
        return response.Data[0];
    }
}

// Usage
var client = new HomaNodeClient(
    "https://endpointplus.homais.com/homanode",
    "10016025",
    "YOUR_TOKEN"
);

var products = client.GetRecords("product", pageSize: 10);
var result = client.InsertRecord("product", new Dictionary<string, object>
{
    ["Title"] = "New Product",
    ["Price"] = 100000
});

Java Example

import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import java.util.*;

public class HomaNodeAPI {
    private final HttpClient httpClient;
    private final String baseUrl;
    private final String portalCode;
    private final String token;
    private final Gson gson;

    public HomaNodeAPI(String baseUrl, String portalCode, String token) {
        this.baseUrl = baseUrl;
        this.portalCode = portalCode;
        this.token = token;
        this.httpClient = HttpClient.newHttpClient();
        this.gson = new Gson();
    }

    public List<Map<String, Object>> getRecords(String table, int pageNo, int pageSize) throws IOException, InterruptedException {
        String query = String.format("?PortalCode=%s&Token=%s&table=%s&pageNo=%d&pageSize=%d",
            portalCode, token, table, pageNo, pageSize);
        
        HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create(baseUrl + query))
            .GET()
            .build();

        HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
        
        TypeToken<List<Map<String, Object>>> typeToken = new TypeToken<List<Map<String, Object>>>() {};
        return gson.fromJson(response.body(), typeToken.getType());
    }

    public Map<String, Object> insertRecord(String table, Map<String, Object> data) throws IOException, InterruptedException {
        String query = String.format("?PortalCode=%s&Token=%s&table=%s&updateCommand=true",
            portalCode, token, table);
        
        String jsonBody = gson.toJson(data);
        
        HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create(baseUrl + query))
            .POST(HttpRequest.BodyPublishers.ofString(jsonBody))
            .header("Content-Type", "application/json")
            .build();

        HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
        
        List<Map<String, Object>> result = gson.fromJson(response.body(), 
            new TypeToken<List<Map<String, Object>>>(){}.getType());
        return result.get(0);
    }

    public Map<String, Object> updateRecord(String table, int id, Map<String, Object> data) throws IOException, InterruptedException {
        data.put("ID", id);
        return insertRecord(table, data);
    }

    public Map<String, Object> deleteRecord(String table, int id) throws IOException, InterruptedException {
        Map<String, Object> data = new HashMap<>();
        data.put("ID", id);
        data.put("DeleteOrder", true);
        return insertRecord(table, data);
    }
}

// Usage
HomaNodeAPI api = new HomaNodeAPI(
    "https://endpointplus.homais.com/homanode",
    "10016025",
    "YOUR_TOKEN"
);

// Get products
List<Map<String, Object>> products = api.getRecords("product", 1, 10);

// Insert product
Map<String, Object> productData = new HashMap<>();
productData.put("Title", "New Product");
productData.put("Price", 100000);
Map<String, Object> result = api.insertRecord("product", productData);

// Update product
Map<String, Object> updateData = new HashMap<>();
updateData.put("Title", "Updated Product");
updateData.put("Price", 180000);
result = api.updateRecord("product", 123, updateData);

// Delete product
result = api.deleteRecord("product", 123);

Go Example

package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "io"
    "net/http"
    "net/url"
)

type HomaNodeAPI struct {
    BaseURL    string
    PortalCode string
    Token      string
    Client     *http.Client
}

func NewHomaNodeAPI(baseURL, portalCode, token string) *HomaNodeAPI {
    return &HomaNodeAPI{
        BaseURL:    baseURL,
        PortalCode: portalCode,
        Token:      token,
        Client:     &http.Client{},
    }
}

func (api *HomaNodeAPI) GetRecords(table string, pageNo, pageSize int, queryCommand string) ([]map[string]interface{}, error) {
    params := url.Values{}
    params.Set("PortalCode", api.PortalCode)
    params.Set("Token", api.Token)
    params.Set("table", table)
    params.Set("pageNo", fmt.Sprintf("%d", pageNo))
    params.Set("pageSize", fmt.Sprintf("%d", pageSize))
    if queryCommand != "" {
        params.Set("queryCommand", queryCommand)
    }

    req, err := http.NewRequest("GET", api.BaseURL+"?"+params.Encode(), nil)
    if err != nil {
        return nil, err
    }

    resp, err := api.Client.Do(req)
    if err != nil {
        return nil, err
    }
    defer resp.Body.Close()

    body, err := io.ReadAll(resp.Body)
    if err != nil {
        return nil, err
    }

    var result []map[string]interface{}
    if err := json.Unmarshal(body, &result); err != nil {
        return nil, err
    }

    return result, nil
}

func (api *HomaNodeAPI) InsertRecord(table string, data map[string]interface{}) (map[string]interface{}, error) {
    params := url.Values{}
    params.Set("PortalCode", api.PortalCode)
    params.Set("Token", api.Token)
    params.Set("table", table)
    params.Set("updateCommand", "true")

    jsonData, err := json.Marshal(data)
    if err != nil {
        return nil, err
    }

    req, err := http.NewRequest("POST", api.BaseURL+"?"+params.Encode(), bytes.NewBuffer(jsonData))
    if err != nil {
        return nil, err
    }
    req.Header.Set("Content-Type", "application/json")

    resp, err := api.Client.Do(req)
    if err != nil {
        return nil, err
    }
    defer resp.Body.Close()

    body, err := io.ReadAll(resp.Body)
    if err != nil {
        return nil, err
    }

    var result []map[string]interface{}
    if err := json.Unmarshal(body, &result); err != nil {
        return nil, err
    }

    return result[0], nil
}

func (api *HomaNodeAPI) UpdateRecord(table string, id int, data map[string]interface{}) (map[string]interface{}, error) {
    data["ID"] = id
    return api.InsertRecord(table, data)
}

func (api *HomaNodeAPI) DeleteRecord(table string, id int) (map[string]interface{}, error) {
    data := map[string]interface{}{
        "ID":          id,
        "DeleteOrder": true,
    }
    return api.InsertRecord(table, data)
}

// Usage
func main() {
    api := NewHomaNodeAPI(
        "https://endpointplus.homais.com/homanode",
        "10016025",
        "YOUR_TOKEN",
    )

    // Get products
    products, err := api.GetRecords("product", 1, 10, "")
    if err != nil {
        fmt.Printf("Error: %v\n", err)
        return
    }
    fmt.Printf("Products: %+v\n", products)

    // Insert product
    result, err := api.InsertRecord("product", map[string]interface{}{
        "Title": "New Product",
        "Price": 100000,
    })
    if err != nil {
        fmt.Printf("Error: %v\n", err)
        return
    }
    fmt.Printf("Insert result: %+v\n", result)

    // Update product
    result, err = api.UpdateRecord("product", 123, map[string]interface{}{
        "Title": "Updated Product",
        "Price": 180000,
    })
    if err != nil {
        fmt.Printf("Error: %v\n", err)
        return
    }

    // Delete product
    result, err = api.DeleteRecord("product", 123)
    if err != nil {
        fmt.Printf("Error: %v\n", err)
        return
    }
}

Error Handling

Authentication Error

[
  {
    "success": false,
    "code": 401,
    "message": "Token is not valid."
  }
]

Bad Request

[
  {
    "success": false,
    "code": 400,
    "message": "No JSON payload provided."
  }
]

Not Found

[
  {
    "success": false,
    "code": 404,
    "message": "No record found to delete."
  }
]

Server Error

[
  {
    "success": false,
    "code": 500,
    "message": "Error details..."
  }
]

Rate Limits

Currently, there are no hard rate limits. However, please be respectful and avoid excessive requests. Recommended limits:

🚀 HomaNode API - High Performance REST API

Version 1.5.0