API for inserting records into MSSQL tables CS_BOX_COIL, CS_BOX_COIL_OCR, CS_BOX_INVOICE, and API_CUSTOMER_PO on database CSMetal_WELLGROW.
| Environment | URL |
|---|---|
| Production | https://mothercoilpo.csmetal.online |
All paths below are relative to this base URL.
| Item | Value |
|---|---|
| Protocol | HTTPS |
| Request body | JSON (Content-Type: application/json) |
| Character encoding | UTF-8 |
| CORS | Enabled (Access-Control-Allow-Origin: *) |
| Authentication | None (network access to the host is the boundary) |
Success (HTTP 2xx):
{
"ok": true,
"message": "pushed to CS_BOX_COIL",
"table": "CS_BOX_COIL",
"coil_no": "C-12345"
}
Error (HTTP 4xx / 5xx):
{
"ok": false,
"message": "human-readable error description"
}
Duplicate invoice errors also include "status": "INVOICE_DUPLICATE" (see Box Invoice Push).
null — they are not written to the database."") are treated as omitted."2026-05-20T14:30:00" or "2026-05-20T14:30:00Z".Verify API and database connectivity before integrating.
GET /api/health
Success (200)
{
"ok": true,
"message": "database reachable"
}
Example
curl -s https://mothercoilpo.csmetal.online/api/health
Inserts one row into CS_BOX_COIL.
POST /api/box-coil-push
| JSON field | DB column | Type | Max length |
|---|---|---|---|
coil_no | COIL_NO | string | 150 |
| JSON field | DB column | Type | Notes |
|---|---|---|---|
po_no | PoNo | string | max 150 |
invoice_no | INVOICE_NO | string | max 150 |
spec_and_grade | SPEC_AND_GRADE | string | max 250 |
mill_mat_spec | MILL_MAT_SPEC | string | max 150 |
cs_mat_spec | CS_MAT_SPEC | string | max 150 |
thickness | THICKNESS | number (decimal) | |
width | WIDTH | number (decimal) | |
length | LENGTH | integer | |
product_mass | PRODUCT_MASS | integer | |
mill_name | MILL_NAME | string | max 250 |
mill_plant_cd | MILL_PLANT_CD | string | max 50 |
mill_plant_name | MILL_PLANT_NAME | string | max 150 |
customer_name | CUSTOMER_NAME | string | max 150 |
send_date_time | SEND_DATE_TIME | datetime (ISO) | If omitted, server sets current UTC time |
{
"ok": true,
"message": "pushed to CS_BOX_COIL",
"table": "CS_BOX_COIL",
"coil_no": "C-12345",
"invoice_no": "INV-2026-001"
}
curl -s -X POST https://mothercoilpo.csmetal.online/api/box-coil-push \
-H "Content-Type: application/json" \
-d '{
"coil_no": "C-12345",
"po_no": "PO-2026-001",
"invoice_no": "INV-2026-001",
"spec_and_grade": "SPCC 1.0x1200",
"thickness": 1.0,
"width": 1200,
"length": 2500,
"product_mass": 18000,
"mill_name": "Example Mill",
"customer_name": "Example Customer"
}'
const response = await fetch("https://mothercoilpo.csmetal.online/api/box-coil-push", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
coil_no: "C-12345",
po_no: "PO-2026-001",
thickness: 1.0,
width: 1200,
}),
});
const data = await response.json();
if (!response.ok || !data.ok) {
throw new Error(data.message || "box-coil-push failed");
}
console.log(data);
| Code | Meaning |
|---|---|
| 201 | Row inserted |
| 400 | Validation error (e.g. missing coil_no, no valid fields) |
| 500 | Database error |
Inserts one row into CS_BOX_INVOICE.
INVOICE_NO is the primary key. Duplicate invoice_no values are rejected.
POST /api/box-invoice-push
| JSON field | DB column | Type | Max length |
|---|---|---|---|
invoice_no | INVOICE_NO | string (PK) | 150 |
| JSON field | DB column | Type | Notes |
|---|---|---|---|
po_no | PoNo | string | max 150 |
vessel_name | VESSEL_NAME | string | max 150 |
shipping_mark | SHIPPING_MARK | string | max 250 |
total_amount | TOTAL_AMOUNT | number (decimal) | |
grand_total_amount | GRAND_TOTAL_AMOUNT | number (decimal) | |
total_net_wt | TOTAL_NET_WT | integer | |
total_gross_wt | TOTAL_GROSS_WT | integer | |
bl_date | BL_DATE | datetime (ISO) | |
bl_no | BL_NO | string | max 150 |
shippint_agency | SHIPPINT_AGENCY | string | max 50 — DB column spelling |
port_of_landing_eta | PORT_OF_LANDING_ETA | datetime (ISO) | |
port_of_discharge_eta | PORT_OF_DISCHARGE_ETA | datetime (ISO) | |
net_wt | NET_WT | integer | |
gross_wt | GROSS_WT | integer | |
total_no_package | TOTAL_NO_PACKAGE | integer | |
port_of_loading | PORT_OF_LOADING | string | max 50 |
port_of_discharge | PORT_OF_DISCHARGE | string | max 50 |
payment | PAYMENT | string | max 150 |
hs_code | HS_CODE | string | max 50 |
{
"ok": true,
"message": "pushed to CS_BOX_INVOICE",
"table": "CS_BOX_INVOICE",
"invoice_no": "INV-2026-001"
}
Returned when invoice_no already exists in CS_BOX_INVOICE.
{
"ok": false,
"status": "INVOICE_DUPLICATE",
"message": "invoice already exists: INV-2026-001",
"invoice_no": "INV-2026-001"
}
curl -s -X POST https://mothercoilpo.csmetal.online/api/box-invoice-push \
-H "Content-Type: application/json" \
-d '{
"invoice_no": "INV-2026-001",
"po_no": "PO-2026-001",
"vessel_name": "MV EXAMPLE",
"bl_no": "BL-999",
"bl_date": "2026-05-20T10:00:00",
"total_amount": 50000.50,
"grand_total_amount": 52000.00,
"total_net_wt": 18000,
"total_gross_wt": 18500,
"port_of_loading": "BKK",
"port_of_discharge": "SGSIN",
"payment": "L/C",
"hs_code": "7209"
}'
import requests
url = "https://mothercoilpo.csmetal.online/api/box-invoice-push"
payload = {
"invoice_no": "INV-2026-001",
"vessel_name": "MV EXAMPLE",
"bl_no": "BL-999",
"total_amount": 50000.50,
}
resp = requests.post(url, json=payload, timeout=30)
data = resp.json()
if resp.status_code == 409 and data.get("status") == "INVOICE_DUPLICATE":
raise RuntimeError(f"duplicate invoice: {data.get('invoice_no')}")
if not resp.ok or not data.get("ok"):
raise RuntimeError(data.get("message", resp.text))
print(data)
| Code | Meaning |
|---|---|
| 201 | Row inserted |
| 400 | Validation error (e.g. missing invoice_no, no valid fields) |
| 409 | Duplicate invoice_no (status: INVOICE_DUPLICATE) |
| 500 | Database error |
Inserts one row into CS_BOX_COIL_OCR (OCR-extracted coil / packing-list data).
POST /api/ocr-coil-push
| JSON field | DB column | Type | Max length |
|---|---|---|---|
coil_no | COIL_NO | string | 150 |
| JSON field | DB column | Type | Notes |
|---|---|---|---|
mill_mat_spec | MILL_MAT_SPEC | string | max 150 |
cs_mat_spec | CS_MAT_SPEC | string | max 150 |
thickness | THICKNESS | number (decimal) | |
width | WIDTH | number (decimal) | |
net_wt | NET_WT | integer | |
unit_price | UNIT_PRICE | number (decimal) | |
po_no | PO_NO | string | max 50 |
invoice_no | INVOICE_NO | string | max 150 |
invoice_date | INVOICE_DATE | datetime (ISO) | |
pl_ref | PL_REF | string | max 150 |
insurance_cert_no | INSURANCE_CERT_NO | string | max 150 |
bl_no | BL_NO | string | max 50 |
vessel | VESSEL | string | max 50 |
eta_thailand | ETA_THAILAND | string | max 50 |
millsheet_no | MILLSHEET_NO | string | max 50 |
list_generation_date | LIST_GENERATION_DATE | datetime (ISO) | |
coil_price | COIL_PRICE | number (decimal) |
{
"ok": true,
"message": "pushed to CS_BOX_COIL_OCR",
"table": "CS_BOX_COIL_OCR",
"coil_no": "C-OCR-001",
"invoice_no": "INV-2026-001"
}
curl -s -X POST https://mothercoilpo.csmetal.online/api/ocr-coil-push \
-H "Content-Type: application/json" \
-d '{
"coil_no": "C-OCR-001",
"po_no": "PO-2026-001",
"invoice_no": "INV-2026-001",
"mill_mat_spec": "SPCC",
"thickness": 1.2,
"width": 1000,
"net_wt": 8500,
"unit_price": 42.5,
"vessel": "MV EXAMPLE",
"invoice_date": "2026-05-20T10:00:00"
}'
| Code | Meaning |
|---|---|
| 201 | Row inserted |
| 400 | Validation error (e.g. missing coil_no, no valid fields) |
| 500 | Database error |
Inserts one row into API_CUSTOMER_PO (customer purchase-order line data).
POST /api/customer-po-push
| JSON field | DB column | Type | Max length |
|---|---|---|---|
po_no | PO_NO | string | 50 |
| JSON field | DB column | Type | Notes |
|---|---|---|---|
customer | CUSTOMER | string | max 50 |
source_file | SOURCE_FILE | string | max 150 |
document_type | DOCUMENT_TYPE | string | max 50 |
contract_no | CONTRACT_NO | string | max 150 |
vendor_part_no | VENDOR_PART_NO | string | max 150 |
part_name | PART_NAME | string | max 150 |
mat_spec | MAT_SPEC | string | max 150 |
thickness | THICKNESS | number (decimal) | |
width | WIDTH | number (decimal) | |
length | LENGTH | string | max 50 |
size | SIZE | string | max 50 |
qty | QTY | integer | |
unit | UNIT | string | max 50 |
due_date | DUE_DATE | datetime (ISO) | |
unit_price | UNIT_PRICE | number (decimal) | |
amount | AMOUNT | number (decimal) | |
remark | REMARK | string | max 250 |
update_time | UPDATE_TIME | datetime (ISO) | If omitted, server sets current UTC time |
{
"ok": true,
"message": "pushed to API_CUSTOMER_PO",
"table": "API_CUSTOMER_PO",
"po_no": "PO-2026-001"
}
curl -s -X POST https://mothercoilpo.csmetal.online/api/customer-po-push \
-H "Content-Type: application/json" \
-d '{
"po_no": "PO-2026-001",
"customer": "Example Customer",
"document_type": "PO",
"part_name": "Steel Coil",
"mat_spec": "SPCC",
"thickness": 1.2,
"width": 1000,
"qty": 5,
"unit": "COIL",
"unit_price": 42.5,
"amount": 212.5,
"due_date": "2026-06-30T00:00:00"
}'
| Code | Meaning |
|---|---|
| 201 | Row inserted |
| 400 | Validation error (e.g. missing po_no, no valid fields) |
| 500 | Database error |
| Page | URL |
|---|---|
| Home | https://mothercoilpo.csmetal.online/ |
| Box coil form | /box-coil |
| OCR coil form | /ocr-coil |
| Box invoice form | /box-invoice |
| Customer PO form | /customer-po |
| API docs (this page) | /api-docs |
| Item | Location |
|---|---|
| FastAPI app | /home/csmetal-mothercoilpo/app/main.py |
| Coil / OCR coil endpoints | /home/csmetal-mothercoilpo/app/routers/coil.py |
| Customer PO endpoint | /home/csmetal-mothercoilpo/app/routers/customer_po.py |
| Invoice endpoint | /home/csmetal-mothercoilpo/app/routers/invoice.py |
| DB mapping & insert | /home/csmetal-mothercoilpo/app/mssql_db.py |
| Process | uvicorn app.main:app on 127.0.0.1:8095 (proxied by nginx) |
Database: Microsoft SQL Server — CSMetal_WELLGROW (connection is server-side only; clients do not need DB credentials).
GET /api/health and confirm "ok": true.POST with only the required field (coil_no for coil/OCR endpoints, or invoice_no for invoice)."ok": true in the response body.CS_BOX_COIL, CS_BOX_COIL_OCR, CS_BOX_INVOICE, or API_CUSTOMER_PO."ok": false and non-2xx status codes in your client (including 409 INVOICE_DUPLICATE for invoices).| Date | Change |
|---|---|
| 2026-05-20 | Initial document: POST /api/box-coil-push, POST /api/box-invoice-push |
| 2026-05-20 | box-coil-push: added optional invoice_no → INVOICE_NO on CS_BOX_COIL |
| 2026-05-20 | box-invoice-push: reject duplicate INVOICE_NO with HTTP 409 INVOICE_DUPLICATE |
| 2026-05-21 | Added POST /api/ocr-coil-push → CS_BOX_COIL_OCR; sample form at /ocr-coil |
| 2026-06-01 | Added POST /api/customer-po-push → API_CUSTOMER_PO; sample form at /customer-po |