Patch cords plugged into the numbered jack field of an antique telephone switchboard

Planetek · AWS Boardwalk · Plank 2

The city exchange · every call goes through the board

City of Alpenglow Developer API

A working public REST API, governed the way integrators expect. Endpoints are versioned with an honest retirement story, API keys ride usage plans with throttles and daily quotas, and the gateway validates request bodies before any code runs. Like the old city exchange, the switchboard answers, refuses, and meters every call before an office ever picks up. These docs render live from the same OpenAPI spec that deploys the gateway itself.

platform status
permit records
business licenses
facilities

Line 01 Start here

Every endpoint except /v2/status and /v1/ping wants an x-api-key header. This shared demo-tier key is the party line: public by design, because nothing behind it costs real money, and its usage plan (2 requests per second, 2,500 a day) is the guardrail. Partner-tier keys with higher limits exist but are never published.

demo key loading…
loading…

The full machine-readable contract is at /openapi.json, the same file Terraform imports into API Gateway. These docs cannot drift from the deployed API.

Line 02 See the governance work

Six live demos against the real gateway. Each shows the exact request sent and the response that came back, including the ones where the switchboard answers before any application code runs.

A telephone and telegraph office around 1900: two operators at desks, one seated at a small switchboard
The Telephone and Telegraph Office, North Tower of the United States National Museum. Smithsonian Institution, public domain, via Unsplash.

Why an exchange?

Before dial service, an operator sat between every caller and every line: she answered, checked who you were, refused calls that made no sense, and connected the rest. That is an API gateway's whole job. The board answers first; the offices behind it only ever hear well-formed, authorized, rate-limited calls.

Line 03 API reference

The directory, rendered in your browser from /openapi.json. Every operation has a live try it console. Requests go same-origin to the gateway with the demo key attached.

loading spec…

Line 04 Usage plans & your own line

Three tiers meter the same board: the shared party line every visitor uses, personal lines the exchange installs on request, and private trunks issued per integrator.

PlanSteady rateBurstDaily quotaKey distribution
demo (the party line)2 req/s52,500Printed above, shared by every visitor
visitor (your own line)2 req/s5500Self-issued below; expires after ~24h
partner (a private trunk)25 req/s5050,000Issued per integrator, never published

The key you present decides your limits. Exceed the rate and the gateway answers 429 throttled, the busy signal. Exhaust the quota and it answers 429 quota_exceeded until midnight UTC. Application code never sees those requests.

Get your own line installed

The exchange will mint you a real API key on the visitor plan, live, via the keyless POST /v2/platform/keys (you cannot present a key you do not have yet). It is shown once, goes live within a minute or two as the gateway's key cache picks it up, and the nightly sweep removes it about 24 hours later. Issuance is capped per address and per day.

Line 05 Order an export

The asynchronous-job pattern, live: POST /v2/exports answers 202 Accepted immediately with a Location header, the job rides an SQS queue to a worker Lambda, and the finished file comes back as a presigned S3 URL that expires after 15 minutes. The bucket itself is never public.

Line 06 How it's built

openapi.yamlsingle source of truth Terraformimports spec into gateway API Gateway (REST)keys · plans · validators · mock
permits λapx-permits table licenses λapx-licenses table facilities λapx-facilities table status λtable metadata only
platform λmeter · keys · nightly sweep exports λ202 + Location SQSjob queue worker λreads catalogs S3private · presigned URLs

Each microservice is its own Lambda with an IAM role fenced to its own DynamoDB table: the permits service cannot read a license record even by bug. The exports worker is the one deliberate exception — read-only across the catalogs, so the write boundary holds. The docs site is S3 + CloudFront; the API is served same-origin under /v1/* and /v2/*, so there is no CORS surface at all. Idle cost of the whole plank: ~$0.