Download OpenAPI specification:
Describes the SteelSolution partner integration as it maps to Tukang.com's existing order system. Last updated: 2026-08-03
Every request needs X-API-Key and X-Signature headers - see the Authorization panel on each endpoint below for how to compute X-Signature.
Every error looks like this:
{ "message": "Vendor not found", "error_code": "VENDOR_NOT_FOUND" }
Clients should branch on error_code. The message field is intended for human readers and its wording may change.
Each endpoint documents the codes it returns. Two additional codes may be returned by any endpoint: NOT_FOUND (404) when the path or method does not exist, and PAYLOAD_TOO_LARGE (413) when the request body exceeds the size limit below.
Note that a request body which is not valid JSON returns 400 VALIDATION_ERROR even when credentials are absent or incorrect. The body is parsed before credentials are verified. A 400 where a 401 was expected therefore indicates a malformed body.
Requests are validated strictly. A field that is not listed in the schema is rejected with 400 VALIDATION_ERROR rather than ignored, and every string and numeric field has a documented length or range. Send only the fields each endpoint declares.
This applies to nested objects as well as the top level.
Request bodies must be smaller than 8 KB. Normal requests are considerably smaller, so this limit is unlikely to be reached in regular use.
Requests exceeding it are rejected by a web application firewall before they reach this API. The firewall responds with 403 and an HTML body rather than the JSON error format above, and no record of the request is retained on our side. The firewall may also reject requests for other reasons, such as an unrecognised User-Agent.
An HTML response therefore indicates a firewall rejection rather than an API error. Please report the source IP address so that it can be added to the allow list.
Tukang.com calls a single webhook on SteelSolution's CMS whenever a site visit's status changes. Every call carries a status value plus the same record shape as the GET /site-visits/{id} response below - fields not relevant to the current status are null.
Status values, in the order they can occur:
in_progress - vendor has started the site visit.
visit_complete - the site visit itself has ended. rab is not yet
populated at this point, whether or not this job will need one.
estimate_ready - fires separately, later: can be hours to days
after visit_complete, not the same call. rab is now populated,
including a materials list
(each item carrying a Magento-recognizable internal_id), a total
service amount, and a RAB PDF URL. Only fires for jobs that need an
estimate; jobs that do not require one stop after visit_complete.
retention_started - every RAB line item has been marked complete
by the vendor, before final install sign-off. A distinct, earlier
signal from install_complete below, not the same moment.
install_complete - installation work is fully finished.
Failed outbound pushes are retried automatically with backoff, so your receiver must be idempotent. If you ever see a gap, the job status check endpoint below is callable anytime and reflects current state.
Returns up to 5 nearby vendors with profile, reviews, and site-visit cost, pre-filtered to vendors available at the requested slot.
required | object |
| material_type required | string [ 1 .. 100 ] characters |
| qty required | integer [ 1 .. 1000000 ] |
| contact_number required | string [ 1 .. 20 ] characters |
| preferred_slot required | string <date-time> [ 1 .. 40 ] characters |
| renovation_or_new_build required | string [ 1 .. 100 ] characters |
{- "location": {
- "lat": -6.2088,
- "lng": 106.8456
}, - "material_type": "Light Steel",
- "qty": 12,
- "contact_number": "+6281234567890",
- "preferred_slot": "2026-07-10T09:00:00+07:00",
- "renovation_or_new_build": "Bangun Baru"
}{- "message": "",
- "result": [
- {
- "vendor_id": "VND0001122",
- "name": "Budi Konstruksi",
- "rating": 4.8,
- "review_count": 126,
- "site_visit_cost": 150000,
- "distance": "3.2 km",
- "city": "Bekasi",
- "about_us": "10 tahun pengalaman renovasi rumah...",
- "certificates": "Sertifikat K3, ...",
- "bluescope_certified": true,
- "k3_certified": true,
- "bnsp_certified": true,
- "jobs_completed": 142,
- "reviews": [
- {
- "customer_name": "Andi",
- "rating": 5,
- "feedback": "Kerja rapi dan tepat waktu",
- "created_date": "2026-06-20"
}
]
}, - {
- "vendor_id": "VND0003344",
- "name": "PT Konstruksi Baja Nusantara",
- "rating": null,
- "review_count": 0,
- "site_visit_cost": 150000,
- "distance": "8.1 km",
- "city": "Tangerang",
- "about_us": "Kontraktor konstruksi baja...",
- "certificates": "",
- "bluescope_certified": true,
- "k3_certified": false,
- "bnsp_certified": false,
- "portfolio": [ ],
- "jobs_completed": 0,
- "reviews": [ ]
}
]
}Called once the customer's site-visit fee payment succeeds. Payment amount is fixed on Tukang.com's side and not accepted from this request.
| order_id required | string SteelSolution's own order id. |
| vendor_id required | string Vendor selected by the customer from the match response. |
| name required | string |
| email required | string <email> |
| phone required | string |
| renovation_or_new_build required | string |
| material_type required | string |
| qty required | integer |
| city required | string City name (kota/kabupaten). |
| district required | string District name (kecamatan). |
| village required | string Village name (desa/kelurahan). |
| job_location required | string |
| job_location_lat required | number <float> |
| job_location_lng required | number <float> |
| job_location_detail | string or null |
| job_time required | string <date-time> |
| photo_url_1 | string or null |
| photo_url_2 | string or null |
| notes | string or null |
{- "order_id": "SH-000123456",
- "vendor_id": "VND0001122",
- "name": "Andi Wijaya",
- "email": "andi.wijaya@example.com",
- "phone": "81234567890",
- "renovation_or_new_build": "Bangun Baru",
- "material_type": "Light Steel",
- "qty": 12,
- "city": "Jakarta Selatan",
- "district": "Kebayoran Baru",
- "village": "Senayan",
- "job_location": "Jl. Merdeka No. 1",
- "job_location_lat": -6.2088,
- "job_location_lng": 106.8456,
- "job_location_detail": "Belakang gudang",
- "job_time": "2026-07-10T09:00:00+07:00",
- "photo_url_2": null,
- "notes": "Renovasi"
}{- "message": "Success create order",
- "result": {
- "site_visit_id": "7501130001",
- "status": "scheduled"
}
}Called once material for the order has been marked received. Notifies the assigned vendor to prepare for the job.
| order_id required | string SteelSolution's own order id (same value sent to /site-visits). |
| received_at required | string <date-time> |
{- "order_id": "SH-000123456",
- "received_at": "2026-07-10T09:00:00+07:00"
}{- "message": "Success log material received",
- "result": {
- "site_visit_id": "7501130001"
}
}Optional status check, callable anytime for an order that exists in the system. rab is only present once a cost estimate exists for the order. job_time always reflects the current scheduled time, including after a reschedule.
| id required | string |
{- "message": "",
- "result": {
- "site_visit_id": "7501130001",
- "status": "estimate_ready",
- "vendor": {
- "id": "VND0001122",
- "name": "Budi Konstruksi"
}, - "customer_name": "Andi Wijaya",
- "job_location": "Jl. Merdeka No. 1",
- "job_time": "2026-07-10T09:00:00+07:00",
- "work_list": "Jenis: Bangun Baru, Material: Light Steel, Qty: 12",
- "notes": "Renovasi",
- "photo_url_2": null,
- "rab": {
- "quote_amount": 5000000,
- "start_time": "2026-07-12",
- "duration": 14,
- "retention_day": 7,
- "total_service_amount": 1500000,
- "materials": [
- {
- "internal_id": "SH-MTL-00042",
- "name": "Baja Ringan C75",
- "qty": 12,
- "unit": "batang",
- "price": 85000
}
]
}, - "complete_work_title": null,
- "complete_notes": null,
- "complete_photo_url_1": null,
- "complete_photo_url_2": null,
- "created_at": "2026-07-06T14:00:00+07:00",
- "last_modify_at": "2026-07-08T09:00:00+07:00"
}
}Called when the customer rejects the estimate/quotation.
| id required | string |
| reject_notes | string or null Free-text reason for rejection (optional). |
{- "reject_notes": "Harga terlalu tinggi"
}{- "message": "Success reject estimate",
- "result": {
- "site_visit_id": "7501130001",
- "status": "closed"
}
}Called once the customer accepts the estimate/quotation and payment succeeds. Payment amount is fixed on Tukang.com's side and not accepted from this request.
| id required | string |
No fields required.
{ }{- "message": "Success accept estimate",
- "result": {
- "site_visit_id": "7501130001",
- "status": "in_progress"
}
}