Water alkalinity converter
One dKH from an aquarium test kit equals 17.848 mg/L as calcium carbonate. The converter moves alkalinity between eight units, including meq/L, ppm, French and English degrees and grains per gallon, for tank, lab and utility readings. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
Worked example
- Value
- 120
- Source unit
- mg/L
- Target unit
- meq/L
- Result
- 2.3979377735
- From label
- milligrams per liter as CaCO3
- To label
- milliequivalents per liter
- Mg l caco3
- 120
A water alkalinity converter turns a carbonate alkalinity reading written in one common unit into another without hunting tables for milligrams per liter calcium carbonate, milliequivalents per liter, or German degrees of carbonate hardness.
Supported alkalinity units and exact CaCO3 factors
The converter accepts eight alkalinity families under stable canonical codes: mg/L for milligrams per liter as calcium carbonate, ppm for parts per million as CaCO3 (numerically identical to mg/L in dilute aqueous samples), meq/L for milliequivalents per liter, dKH for German degrees of carbonate hardness also known as degrees KH or °dH, °f for French degrees, °e for English or Clark degrees, mmol/L for millimoles per liter as CaCO3, and gpg for grains per US gallon as CaCO3.
Factors follow standard water-chemistry practice: one milligram per liter equals one milligram per liter; one ppm equals one milligram per liter; one meq/L equals fifty point zero four three milligrams per liter because the equivalent weight of CaCO3 is one hundred point zero eight six nine divided by two; one dKH equals seventeen point eight four eight milligrams per liter; one French degree equals ten milligrams per liter; one English degree equals one hundred divided by seven milligrams per liter; one mmol/L equals one hundred point zero eight six nine milligrams per liter; and one grain per US gallon equals seventeen point one one eight zero six one milligrams per liter.
Because the intermediate is always mg/L as CaCO3, converting A to B and B to A is consistent up to the published rounding of twelve decimal places, and there is no pairwise matrix that can drift out of sync.
Where it helps with everyday water checks
Use the free in-browser water alkalinity converter when you need a quick milligrams-per-liter to milliequivalents-per-liter or degrees-KH check while reading a lab report, aquarium test kit, municipal water quality sheet, or process control log. Open the page, enter the number and units, and copy the result without installing a spreadsheet, a unit library, or a desktop calculator pack. Source inputs follow the same retention rules as other KIT parse items, and results are safe to cache because the algorithm is fully deterministic.
Authors shipping mobile apps or chatbots can map the result and formula fields directly into cards that show both the number and the conversion path aquarists, plant operators, and lab technicians expect on paper.
What you can do with it
Aquarium and reef tank KH checks
Convert test-kit dKH or degrees KH readings into mg/L as CaCO3 or meq/L so dosing calculators and controllers share one alkalinity scale.
Drinking-water and utility reports
Normalize mixed lab units—ppm CaCO3, meq/L, French or English degrees—into a single milligrams-per-liter column for compliance dashboards.
FAQ
What is dKH and how does it relate to degrees KH?
dKH is German degrees of carbonate hardness, also written °dH, °KH, or degrees KH. One dKH equals 17.848 mg/L as CaCO3.
What happens if I send an unknown unit?
The error message names the field and lists supported units: mg/L, ppm, meq/L, dKH, °f, °e, mmol/L, and gpg. Validation failures are not charged.
Is the water alkalinity converter free?
The browser tool runs free on your device.
Are ppm and mg/L the same for alkalinity?
For dilute aqueous samples, one ppm as CaCO3 is numerically equal to one mg/L as CaCO3. This converter treats them as identical factors of one into the mg/L intermediate.
How do I convert meq/L to mg/L as CaCO3?
Multiply by 50.043, because the equivalent weight of calcium carbonate is 100.0869 divided by two. Going the other way, 120 mg/L as CaCO3 becomes 2.397937773515 meq/L.
Related tools
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, by email and from Telegram — and soon from our app too.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/conv/alkalinity \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"value":120,"from":"mg/L","to":"meq/L"}'const res = await fetch("https://api.kit.forhosting.com/conv/alkalinity", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"value": 120,
"from": "mg/L",
"to": "meq/L"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/conv/alkalinity",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"value": 120,
"from": "mg/L",
"to": "meq/L"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/conv/alkalinity", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"value":120,"from":"mg/L","to":"meq/L"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"value":120,"from":"mg/L","to":"meq/L"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/conv/alkalinity", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"value": 120,
"from": "mg/L",
"to": "meq/L"
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "conv.alkalinity",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |
Technical notes
The browser tool runs free on your device; the prepaid API charges $0.002 per successful item when aquariums, utilities, labs, and pipelines need the same contract from servers and automation.
Supported alkalinity units and exact CaCO3 factors
Friendly aliases such as milligrams per liter, milliequivalents per liter, degrees KH, German hardness, French degrees, Clark, and grains per gallon are normalized case-insensitively so forms and APIs can pass either short codes or full names. Every request multiplies the input value by the exact milligrams-per-liter factor for the source, then divides by the milligrams-per-liter factor for the target. Titration endpoint calculation and raw acid-volume math are intentionally out of scope so this landing stays a pure unit converter.
Request shape, response fields, and unknown-unit errors
The error message names the bad field and lists the supported set so clients can correct forms without guessing. Negative values are allowed when you need signed alkalinity deltas in process-control pipelines; zero converts cleanly to zero in every target unit. Send a JSON body with three required fields: value as a finite number, from as the source unit string, and to as the target unit string. Aliases amount, quantity, and alkalinity are accepted for value; unit_from and source for from; unit_to and target for to. On success the response echoes the canonical from and to codes, human-readable from_label and to_label strings, the converted result, the intermediate mg_l_caco3 quantity, the dimensionless factor from source to target, a short formula line suitable for UI display, the method tag alkalinity_caco3, and the fixed list of units_supported. Missing value, non-finite numbers such as NaN or Infinity, missing unit fields, and any token that does not map to a supported unit fail with invalid_input and are not charged after the engine rejects the request. Identical inputs always yield identical JSON because the path is pure arithmetic with no randomness, no remote lookup, and no dependence on the wall clock, which makes the endpoint safe to pin in continuous-integration goldens and SDK contract tests. Aquarium-scale results near one hundred twenty milligrams per liter and utility-scale results near several hundred milligrams per liter share the same code path, so magnitude pairs remain well-defined as long as IEEE double precision can represent the intermediate product.
Browser use, API pricing, and everyday water workflows
Switch to the prepaid API when a reef-tank controller, drinking-water quality dashboard, industrial cooling-water softener monitor, environmental lab LIMS, or educational chemistry chatbot must convert alkalinity units at scale under a stable KIT contract at $0.002 per successful item; validation failures that raise invalid_input do not consume balance after rejection. Pair this endpoint with hardness or pH tools when search traffic starts from a broader water-chemistry intent, or call it alone when the query is specifically for converting alkalinity among mg/L CaCO3, meq/L, dKH, and related degree systems.
Integration use cases
Lab LIMS and process control APIs
Accept operator or instrument unit strings, return a deterministic converted alkalinity, and raise invalid_input on unknown tokens under a prepaid KIT contract.
Technical questions
How do I convert mg/L as CaCO3 to meq/L?
Send JSON with value set to the reading, from: "mg/L", and to: "meq/L". The engine divides by 50.043 (the equivalent weight of CaCO3 in mg/meq) and returns result plus the intermediate mg_l_caco3 field.