Polygon interior angles from ordered vertices
This polygon interior angles calculator takes the ordered Cartesian coordinates of a simple polygon and computes the angle inside the shape at every vertex.
Run — free
It works for convex and concave polygons, so a recessed corner can correctly produce a reflex angle greater than 180 degrees. The response preserves vertex order, reports all measurements in degrees, identifies the winding direction, and includes the theoretical total angle sum. That makes the result useful for geometry checks, drawing tools, coordinate-data validation, and reproducible automated workflows.
Enter an ordered polygon boundary
Provide at least three vertices as objects with finite numeric x and y coordinates. The order must follow the polygon boundary continuously, either clockwise or counterclockwise. Do not repeat the first point at the end because the calculator closes the last edge automatically. The coordinates describe a flat Cartesian plane; they may represent drawing units, meters in a projected coordinate system, pixels, or any other consistent linear scale. They are not interpreted as longitude and latitude on a curved Earth. A valid input must describe a simple polygon: neighboring vertices cannot be identical, no vertex may be duplicated elsewhere, the enclosed area must be nonzero, and nonadjacent edges cannot cross or touch. These rules matter because an interior angle is ambiguous when a ring folds over itself. If validation fails, the response identifies the relevant vertex or edge condition instead of returning plausible-looking measurements for invalid geometry. The maximum vertex count keeps the deterministic browser and API execution bounded.
Understand convex, concave, and reflex results
For each vertex, the calculator forms vectors from the current point toward its previous and next neighbors. Their dot product and cross product determine the local angle and turn direction. Signed polygon area establishes whether the complete boundary runs clockwise or counterclockwise. Combining the local turn with that winding is what distinguishes an ordinary convex corner from a concave corner whose interior is the reflex complement. Consequently, a convex rectangle returns four 90-degree values, while an inward notch can return an angle greater than 180 degrees at the recessed vertex. The angles_deg array uses exactly the same order as the input vertices, so index zero always describes the first supplied point. Results are rounded to ten decimal places to avoid distracting floating-point tails while retaining ample precision for common geometry work. Collinear boundary points may yield a 180-degree angle when they do not create an invalid overlap. The winding field describes orientation only; reversing the entire input order changes that field but preserves the corresponding geometric angle at each coordinate.
Check the total and use the output safely
Every simple polygon with n vertices has an interior-angle total of (n − 2) × 180 degrees, regardless of whether it is convex or concave. The total_sum_deg field reports that invariant directly, while vertex_count supplies n. This total is useful as a fast consistency check when importing geometry from CAD exports, digitized outlines, educational exercises, or custom drawing applications. The individual rounded values can differ from an independently accumulated floating-point sum by a tiny amount, so use total_sum_deg as the authoritative theoretical total rather than summing display values and demanding bit-for-bit equality. The capability is deterministic: the same ordered coordinates always produce the same JSON, and it uses no network service, random source, or current time. You can run it freely in the browser for interactive work or call the API for $0.002 per request when incorporating the calculation into a pipeline. Keep all coordinates in one planar reference system, and project geographic data before using this calculator when curvature would materially affect the intended geometry.
What you can do with it
Validate a drawing tool
Compare corner measurements and the theoretical total after a user edits an ordered polygon path.
Inspect concave geometry
Identify reflex angles at inward corners without assuming that every polygon is convex or regular.
Grade coordinate exercises
Generate deterministic per-vertex angles and the expected sum for polygons supplied as coordinate lists.
FAQ
Does this work for concave polygons?
Yes. It uses winding and local turn direction to return reflex interior angles greater than 180 degrees where appropriate.
Should I repeat the first vertex at the end?
No. The closing edge is implicit, and repeating the first vertex is rejected as a duplicate.
Can I use latitude and longitude directly?
Only when treating them as approximate planar coordinates is acceptable. For meaningful geographic geometry, project them into a suitable Cartesian coordinate system first.
Why was my polygon rejected?
Common causes are fewer than three vertices, non-finite coordinates, duplicate points, zero-length edges, zero area, or intersections between nonadjacent edges.
What does the API request cost?
Each API request costs $0.002. The same deterministic calculation is also available in the browser.
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/geo/polygon-interior-angles \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"vertices":[{"x":0,"y":0},{"x":4,"y":0},{"x":4,"y":3},{"x":0,"y":3}]}'const res = await fetch("https://api.kit.forhosting.com/geo/polygon-interior-angles", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"vertices": [
{
"x": 0,
"y": 0
},
{
"x": 4,
"y": 0
},
{
"x": 4,
"y": 3
},
{
"x": 0,
"y": 3
}
]
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/geo/polygon-interior-angles",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"vertices": [
{
"x": 0,
"y": 0
},
{
"x": 4,
"y": 0
},
{
"x": 4,
"y": 3
},
{
"x": 0,
"y": 3
}
]
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/geo/polygon-interior-angles", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"vertices":[{"x":0,"y":0},{"x":4,"y":0},{"x":4,"y":3},{"x":0,"y":3}]}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"vertices":[{"x":0,"y":0},{"x":4,"y":0},{"x":4,"y":3},{"x":0,"y":3}]}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/geo/polygon-interior-angles", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"vertices": [
{
"x": 0,
"y": 0
},
{
"x": 4,
"y": 0
},
{
"x": 4,
"y": 3
},
{
"x": 0,
"y": 3
}
]
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "geo.polygon_interior_angles",
"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. |