Quick start
- As a verified municipal manager, open your municipality’s API keys. Create a separate key for each integration, with permissions restricted as far as possible.
- Copy the key immediately after creating it. It is shown only once. Store it in your server’s protected configuration.
- Send it only in the Authorization header as a Bearer token. The municipality slug and public report code determine the endpoint.
- Test read access first. Enable write or internal scopes only when the connected tool actually needs them.
Authorization: Bearer <API_KEY>
Accept: application/json
Content-Type: application/json
Keys belong on your serverDo not use API keys in public websites, mobile apps, URLs or publicly accessible source code. For a public widget, use your own server as an intermediary and pass on only the public data needed.
Keys are bound to exactly one municipality and their authorised creator. Revocation, expiry or loss of administrative permissions blocks access. New keys expire after 90 days by default; the maximum is 365 days.
Permissions
The four scopes are granted separately. Write scopes do not automatically include read scopes. For a complete read and write workflow, select the corresponding pair of scopes.
Scopes per API key| Scope | Permits | Limit |
public:read | Read and search public issues. | Only details that are already publicly visible; waiting periods and approvals still apply. |
public:write | Update the public status and a reasoned response. | Only published issues from your own municipality and permitted status changes. |
internal:read | Read internal notes; together with public:read, also retrieve internal issue views. | Still requires the municipal plan for internal collaboration, available from Plan 3. |
internal:write | Add internal notes. | Does not permit public changes and also requires Plan 3. |
Internal data must be requested explicitly. The default remains public. Even authorised internal access does not return complete user accounts, passwords or arbitrary database fields.
To write public updates, you also need public:read to obtain the current edit version. For internal notes, the pair internal:read and internal:write is sufficient.
Endpoints
Base URL: https://www.region360.dev/api/v1
Municipality API v1| HTTP | Path relative to the base URL | Permission |
| GET | /municipalities/{municipality}/reports | public:read |
| GET | /municipalities/{municipality}/reports/{report} | public:read |
| GET | /municipalities/{municipality}/reports/{report}/comments | public:read |
| PATCH | /municipalities/{municipality}/reports/{report}/progress | public:write |
| GET | /municipalities/{municipality}/reports/{report}/notes | internal:read |
| POST | /municipalities/{municipality}/reports/{report}/notes | internal:write |
municipality is the municipality slug from the URL; report is the public report code. The API supports problems and ideas. Creating issues, deleting data and uploading files are not supported in this version.
The list supports q, type, status, page and per_page. A maximum of 100 entries is returned per page. visibility=internal requires both read scopes; without this parameter, you receive the public view.
Status codes remain language-independent: open, progress, external and done. Dates use ISO 8601; structural details and all permitted values are provided in the OpenAPI document.
Code examples
The examples use environment variables for the key and fictional identifiers. Replace the identifiers with your own municipality and report code.
Read public issues · cURL
curl --fail-with-body \
-H "Authorization: Bearer $REGION360_API_KEY" \
-H 'Accept: application/json' \
'https://www.region360.dev/api/v1/municipalities/sonnental/reports?per_page=20'
Public update · server-side JavaScript
const base = process.env.REGION360_BASE_URL;
const headers = {
Authorization: `Bearer ${process.env.REGION360_API_KEY}`,
Accept: 'application/json',
'Content-Type': 'application/json'
};
const path = '/municipalities/sonnental/reports/ABCD-2345';
const current = await fetch(`${base}${path}`, { headers });
if (!current.ok) throw new Error(`Region360: ${current.status}`);
const { data } = await current.json();
const result = await fetch(`${base}${path}/progress`, {
method: 'PATCH', headers,
body: JSON.stringify({
edit_version: data.edit_version,
status: 'progress',
message: 'Die Reparatur ist eingeplant.'
})
});
if (result.status === 409) {
throw new Error('Version conflict: reload and review before retrying.');
}
if (!result.ok) throw new Error(`Region360: ${result.status}`);
REGION360_BASE_URL contains the full base URL including /api/v1. After a version conflict, do not retry a write without reviewing it: reload the current state and decide based on the changes.
Errors & version conflicts
401- The key is missing, invalid, expired or revoked; loss of administrative permissions also blocks access.
403- The required scope, municipal permission or plan is missing.
404- The municipality or issue is not available to this key.
409- The edit version is outdated. Reload the current state and review your changes.
422- Inputs are incomplete or invalid. Review the field errors.
429- Too many requests. Pause and follow the rate-limit information.
Every write request requires the current edit_version. Version checking prevents accidental overwrites between your tool and the municipal portal. A timeout alone does not prove that a change failed: check the current history before retrying a write.
SDK and operations
The OpenAPI document describes authentication, requests and responses in a machine-readable format. You can import it into OpenAPI-compatible tools to generate clients for your programming language.
Use a separate key per integration, document who is responsible and renew keys before they expire. If you suspect disclosure, revoke the key immediately in the municipal portal.
Paths under /api/v1 and technical field names are not translated with the interface language. This keeps integrations stable when the language changes.
Open OpenAPI document